# Types

> The values your app computes with, and the declarations that name and scope them. Most scalar types are exactly C#'s — int, long, double, string, bool, Guid work as you expect. The pages here cover the ones with a wrinkle worth knowing up front (decimal, long, and the date/time family) and the file-level declarations: namespace, visibility, and use.

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

## Summary        {#summary}
Osy# is C#, so the types are C#'s types. `int`, `long`, `double`, `string`, `bool`, and `Guid` behave exactly as you
expect and need no page of their own. What this area documents is the handful of types with a wrinkle worth knowing
**before** you reach for them — `decimal` and the date/time family — and the three declarations that name and scope
the types you write: `namespace`, visibility, and `use`.

**Looking for the full list?** [Every type, in one list](https://osysharp.com/reference/types/vocabulary/) enumerates every built-in type in one place — the scalars, the
collections, the two callable spellings, and the component-parameter wrappers. Read it when the question is *"is
there a type for this?"* rather than *"how does this one behave?"*.

The one rule that runs through all of it: a value computes to the **same answer on the server and in the browser**,
character for character. A `decimal` total, a `DateTime`'s parts, a `TimeSpan`'s hours — none of them changes with
where the code happens to run.

## Description    {#description}

### The numbers   {#numbers}
Four numeric types, straight from C#: `int` and `long` (whole numbers), `double` (fast, approximate — measurements and
science), and `decimal` (exact base-10 — money, and anything where a fraction of a cent matters). Two earn a page:
[decimal](https://osysharp.com/reference/types/decimal/), because "exact vs approximate" is the choice that quietly decides whether a total is ever a penny
off, and [long](https://osysharp.com/reference/types/long/), because whole-number division truncates and because a 64-bit id is exact to its full range on
both sides. Reach for `decimal` when the number is money, `long` when it is an id or a sequence, `double` when it is a
measurement.

### The date and time family   {#date-and-time}
This is the part to read up front, because the names carry meaning:

- [DateTime](https://osysharp.com/reference/types/datetime/) — a date **and** time. It is a wall-clock value, not an instant on a timeline, so nobody's
  timezone ever shifts it.
- [DateOnly and TimeOnly](https://osysharp.com/reference/types/date-and-time/) — `DateOnly` (a calendar date, no time) and `TimeOnly` (a time of day, no date).
- [TimeSpan (durations)](https://osysharp.com/reference/types/timespan/) — `TimeSpan`, a **duration**: subtract two `DateTime`s and you get one; add it back and you get a
  `DateTime`. Read whole components (`.Days`, `.Hours`) or fractional totals (`.TotalHours`).

[TimeSpan, DateOnly, TimeOnly](https://osysharp.com/reference/types/duration-and-parts/) ties the three together — how they combine, and why all of them are exact and
side-independent.

### The declarations that scope your types   {#scoping}
Three keywords decide where a type lives and who may name it:

- [namespace](https://osysharp.com/reference/types/namespace/) — `namespace X;` at the top of a file puts that file's types in `X`. Optional; omit it and they
  land in the global namespace.
- [type visibility (public / internal)](https://osysharp.com/reference/types/visibility/) — a top-level type is `public` or `internal`, deciding whether code outside its namespace can
  name it. The defaults are C#'s: an entity or enum is `public`, a plain `class` is `internal`.
- [use](https://osysharp.com/reference/types/use/) — `use Osysharp.X;` inside the `app { }` manifest declares a **capability** your app depends on, which
  provisions its tables and types. It is the dependency; a `using` is just the import that brings the names into scope.

### What if my name is already the platform's?   {#shadowing}
The `Osyrin` core namespace is in scope in every app with no `using`, and it exports 82 type names — many of them
ordinary English words (`Slot`, `Group`, `Match`, `Point`, `Month`, `Now`, `Uri`, `Connection`, `Position`). Naming
your own type after one is **legal, and yours wins**; the compiler warns once at the declaration and the platform's
type stays reachable by its full name. [When your name is already the platform's](https://osysharp.com/reference/types/name-shadowing/) has the rule, the full list of taken names, and the
eleven built-in names that are the exception.

### Values the compiler has to know   {#constants}
**Looking for how to DECLARE a named constant? It is `const`, and it goes wherever you need it:**

```syntax
const int EatSoonDays = 90;                       // top level — shared by every function and page in the app
component Home() { const int Rows = 20; … }       // one component
int F() { const int Limit = 5; … }                // one body
class Rules { public const int Retries = 3; }     // on a class, as in C#
```

A `const` folds to its value at every use, so it goes anywhere a literal goes — **including inside a query
predicate**, where a function call cannot (a predicate becomes SQL, and SQL cannot call back into your code). That
is the difference between `const int Days = 90;` and a `int Days() { return 90; }` helper.

For a value that differs between environments — a base URL, a from-address — you want [per-environment config (app.Config)](https://osysharp.com/reference/config/app-config/)
instead, not a constant.

**This section is about something else:** a few places take a value that must be settled while the app is compiled
rather than while it runs — an attribute argument, a config setting, an enum member's label, a workflow message.
[Constant expressions](https://osysharp.com/reference/types/constant-expressions/) covers what counts as constant *there*, including the fact that a long sentence may
be split across lines with `+`.

## See also       {#see-also}
- [Every type, in one list](https://osysharp.com/reference/types/vocabulary/) — EVERY built-in type in one list: scalars, collections, callables, component wrappers
- [decimal](https://osysharp.com/reference/types/decimal/) — exact money arithmetic, and when to prefer it over `double`
- [long](https://osysharp.com/reference/types/long/) — 64-bit whole numbers: ids and sequences, and why division truncates
- [DateTime](https://osysharp.com/reference/types/datetime/) · [TimeSpan (durations)](https://osysharp.com/reference/types/timespan/) · [DateOnly and TimeOnly](https://osysharp.com/reference/types/date-and-time/) — the date/time family
- [namespace](https://osysharp.com/reference/types/namespace/) · [type visibility (public / internal)](https://osysharp.com/reference/types/visibility/) · [use](https://osysharp.com/reference/types/use/) — naming, scoping, and depending
- [When your name is already the platform's](https://osysharp.com/reference/types/name-shadowing/) — the 82 names already in scope, and what happens when you declare one of them yourself
- [string literals — ordinary, verbatim and raw](https://osysharp.com/reference/types/string-literals/) — `"…"`, `@"…"` and `"""…"""`, and the indentation rule that makes a block of prose usable
- [char](https://osysharp.com/reference/types/char/) — one character: `s[0]`, iterating a string, and the `char.*` classification family
- [Constant expressions](https://osysharp.com/reference/types/constant-expressions/) — where a compile-time constant is required, and what folds into one
- [Classes](https://osysharp.com/reference/class/index/) — plain in-memory value shapes; [entity](https://osysharp.com/reference/entity/declaration/) — persisted ones
