# When your name is already the platform's

> The platform puts 82 ordinary English words in scope in every app with no `using` — `Slot`, `Group`, `Match`, `Point`, `Month`, `Now`, `Uri`, `Connection`, `Position`, `Display` … Declaring your own type with one of those names is LEGAL and YOURS WINS everywhere; the compiler NOTES it once, at the declaration, and the platform's type is still reachable by its full name. Nothing is owed and there is nothing to suppress. Eleven names are the exception — the built-in types — and those you cannot take, so those are a warning.

<!-- id: types-name-shadowing · area: types · stability: stable · html: https://osysharp.com/reference/types/name-shadowing/ -->

## Summary        {#summary}
Every app has the `Osyrin` core namespace in scope with **no `using` to write**, and that namespace exports **82
type names**, many of them ordinary English words: `Slot`, `Group`, `Match`, `Point`, `Month`, `Schedule`, `Now`,
`Uri`, `Connection`, `Failure`, `Position`, `Display`, `Cursor`, `Pending`, `Visitor` …

**Declaring your own type with one of those names is legal, and yours wins.** A bare `Slot` anywhere in your app
means *your* `Slot`, in every position — a property type, a local, a parameter, a cast, an enum member access. The
compiler says so once, as a **note at the declaration** (`INFO`, not a warning — nothing is broken and nothing is
owed), and the platform's type stays reachable by its full name (`Osysharp.Workflow.Slot`). Nothing needs renaming: if
`Slot` is the word your domain uses, keep it.

The one exception is the **eleven built-in type names** (`DateTime`, `Json`, `Zone` …) — see [[#built-ins]]. Those
resolve ahead of everything an app declares and have no full spelling, so a type of yours named after one is
unreachable. The compiler warns about those too, and there the remedy is to rename.

## Signature      {#signature}
```osy syntax
enum Slot { Morning, Afternoon }        // legal — and a bare `Slot` now means THIS one, everywhere
Osysharp.Workflow.Slot                    // the platform's, still reachable, by its full name
```

## Description    {#description}

### What happens if I name my type after a platform one?   {#rule}
**Yours wins — the same rule C# uses.** The name you declare in your own app is nearer than a name that arrived from
an import, so it is the one a bare spelling binds to. That holds in *every* position; there is no corner where the
platform's type quietly comes back.

What the compiler owes you is to say it, and it does — once, on the declaration:

```text
model.osy:1  INFO  TYPE_SHADOWS_ALWAYS_IN_SCOPE  `enum Slot` has the same name as 'Osysharp.Workflow.Slot',
             which is in scope in every app with no `using` to write. YOURS WINS: a bare `Slot` anywhere in this
             app means this enum, and 'Osysharp.Workflow.Slot' can only be reached by its full name from here on.
```

That is the whole cost of the collision: a diagnostic that mentions `Slot` may be talking about either type, so you
need to know which one you are reading. There is nothing to accept and nothing to write down — just write the app you
meant to write:

```osy title="the customer's word, kept — and it wins everywhere" test app=types-name-shadowing
enum Slot { Morning, Afternoon, Evening }

entity Booking {
  [Required, MaxLength(120)] string Guest;
  Slot Period;                     // the property type binds to the enum above…
}

Slot PeriodOf(Booking b) {
  Slot pick = Slot.Morning;        // …and so does the local, and the member access
  return b.Period == pick ? pick : b.Period;
}
```

### Can a field be named after its own type?   {#member-named-after-type}
Naming a field after the type it holds is ordinary, and it works:

```osy syntax
component Screen() {
  Valley valley = new Valley();       // the field is named after its own type
  on frame (double dt) {
    valley.Paint();                   // this is the FIELD, not a static call on the type
  }
}
```

A value in scope — a local, a parameter, a class field or a component member — **shadows a type of the same name**,
so `valley.Paint()` is a call on the object you are holding. To reach a `static` member of the type while a value
shadows it, see [[#qualifying]].

### My variable has the same name as my entity — which wins?   {#value-vs-entity}
**Your declaration wins, for as long as it is in scope, and it is decided by its declared TYPE — never by how the
name is spelled.** This is the other axis of the same question, and the same C# answer: a local shadows a type name
in its block, and nobody finds that surprising.

Every binder shadows: a local, a `foreach` variable, a lambda's range variable, a function parameter, a `class`
field read through implicit `this`, and a `component`'s parameters and members read inside an `action` or `method`
body. The entity is untouched everywhere the name is *not* taken — shadowing hides a name, it does not remove one.

```osy title="a field named after an entity is the field; a bare name with nothing in the way is the table" test app=types-name-shadowing
entity Ticket { [Required, MaxLength(80)] string Subject; }

class Envelope {
  public List<string> Ticket;                              // a field named after the entity…
  public int Held() { return Ticket.Take(100).Count; }     // …so this counts the FIELD's strings
}

int InTheStore() { return Ticket.Take(100).Count; }        // nothing shadows it here — the TABLE
```

That matters most for a name you did not choose. A capability you `use` ships components whose parameters were
named without knowing your model — the UI kit alone has `item`, `user`, `entry`, `row` — and you cannot rename
them. They bind to their own declarations, whatever your app calls its entities.

**And the spelling has to match exactly.** Osy# is case-sensitive, as C# is, so `ticket` does not name `Ticket` and
never silently reads it:

```text
model.osy:7  ERROR  RESOLVE_ERROR  unknown identifier 'ticket'. Did you mean 'Ticket'?
```

### Which names are already taken?   {#always-in-scope}
All 82, by the namespace each comes from. Taking one costs you a one-line note and nothing else — this is a list to
recognise a diagnostic by, not a list to avoid.

| Namespace | Names |
|---|---|
| `Osyrin` (51) | `ActionState` · `Align` · `AlignSelf` · `BgSize` · `BorderStyle` · `ConnState` · `Connection` · `Cursor` · `DayOfWeek` · `Display` · `DragAxis` · `Failure` · `FieldSizing` · `FontVariant` · `GridAutoFlow` · `Group` · `GroupCollection` · `Justify` · `MarkdownDocument` · `Match` · `MixBlendMode` · `Month` · `Navigation` · `NavigationRoute` · `Now` · `ObjectFit` · `OutlineStyle` · `Overflow` · `Pending` · `Point` · `PointerEvents` · `Position` · `Resize` · `ScrollBehavior` · `ScrollbarWidth` · `TextAlign` · `TextDecoration` · `TextOverflow` · `TextTransform` · `UiRole` · `UiSort` · `Uri` · `UserSelect` · `Validation` · `VerticalAlign` · `Violation` · `Visibility` · `Visitor` · `WhiteSpace` · `WordBreak` · `Wrapping` |
| `Osysharp.Workflow` (20) | `AuditKind` · `CorrelationOutcome` · `FlowMetrics` · `Leg` · `Losers` · `RequirementStatus` · `Saga` · `ServiceException` · `ServiceHours` · `ServiceWindow` · `SlaKind` · `Slot` · `SlotStatus` · `SlotView` · `StateTime` · `TransitionView` · `WorkflowAuditEntry` · `WorkflowRun` · `WorkflowRunStatus` · `WorkflowRunSummary` |
| `Osysharp.Scheduling` (11) | `Schedule` · `ScheduleExclusion` · `ScheduleFrequency` · `ScheduleOccurrenceOutcome` · `ScheduleOverlap` · `ScheduleRule` · `ScheduleRuleMonth` · `ScheduleRuleMonthDay` · `ScheduleRuleTime` · `ScheduleRuleWeekday` · `ScheduleStatus` |

A capability you `use` brings more names in (the UI kit's controls, for instance). Those follow the same rule and
raise the same note.

### How do I still reach the platform's type?   {#qualifying}
**By its full name**, which is what the note prints. There is nothing else to configure:

```osy title="both types, in one file, each spelled unambiguously" test app=types-name-shadowing
Guid DefinitionOf(Osysharp.Workflow.Slot s) {
  return s.Definition;                      // the PLATFORM's Slot — spelled in full
}

Slot MyDefault() { return Slot.Morning; }   // …and a bare `Slot` is still yours
```

If you ever see a diagnostic like `cannot assign 'Slot' to 'Slot' (type 'Osysharp.Workflow.Slot')`, it now carries a
note saying that the two words are two different types and which one the bare spelling means. That is this rule
speaking at a use site.

### The eleven names you cannot have   {#built-ins}
The **built-in types** are not in a namespace — they are resolved first, ahead of everything an app declares, and
there is no qualified spelling that could reach past them. So a type of yours named after one is **unusable**: the
declaration itself looks fine, and the failure lands later, at a use site.

`DateTime` · `DateOnly` · `TimeOnly` · `TimeSpan` · `Guid` · `Json` · `RichText` · `Markdown` · `Vector` · `Zone` ·
`Culture`

```text
model.osy:1  WARNING  TYPE_SHADOWS_ALWAYS_IN_SCOPE  `enum Zone` has the same name as the BUILT-IN type `Zone` …
             THE BUILT-IN WINS: built-in types resolve ahead of everything an app declares, so a bare `Zone` never
             means this enum — and there is no qualified name that reaches it either, so this enum is unusable.
```

**Rename yours.** `[SuppressWarning]` silences the warning but not the problem — the type stays unreachable. The full
set of built-in types is [Every type, in one list](https://osysharp.com/reference/types/vocabulary/); the ones an entity may store are in [entity members](https://osysharp.com/reference/entity/properties/).

### If you would rather have no collision at all   {#suppress}
You do not have to do anything: the namespace collision is a **note**, so no gate counts it and nothing fails. If you
would rather the two names never met, there are two ways out — rename your type, or put it in a
[namespace](https://osysharp.com/reference/types/namespace/) of its own, which gives it a full name and stops it shadowing anything.

`[SuppressWarning("TYPE_SHADOWS_ALWAYS_IN_SCOPE")]` still works on the declaration if you simply want the line gone
(see [[SuppressWarning]](https://osysharp.com/reference/diagnostics/suppress-warning/)), but it is no longer what the compiler suggests: a note asks for nothing, so
there is nothing to put down. It IS the right tool for the built-in half above, where the warning is real.

## See also       {#see-also}
- [Every type, in one list](https://osysharp.com/reference/types/vocabulary/) — every built-in type in one list
- [namespace](https://osysharp.com/reference/types/namespace/) — `namespace X;`, and why a namespaced type shadows nothing
- [entity members](https://osysharp.com/reference/entity/properties/) — which of these types an entity member may hold
- [[SuppressWarning]](https://osysharp.com/reference/diagnostics/suppress-warning/) — `[SuppressWarning("CODE")]`, and where it may sit
