# The type of a conversion

[Narrowing](../narrowing.md) › conversions. The names in the examples are those of [section 2](../narrowing.md#2-the-names-in-the-examples).

`number`, `string`, `date`, `time`, `date and time`, `duration`, `years and months duration` and `range` make a value of one kind from a value of another, mostly from text (`Feel.Builtin.Conversion`). Their signatures say the kind of the result and that the call can be `null`; the rules of `Feel.Analysis.Images.Conversion` (D-170) say when, and which values: they are held to the run as the other families are (`Feel.ImageCheck`). A rule gives the whole type of the result, in one of two ways.

- **The function is run on the values of a finite set** (at most 64 combinations of them). The strings of a list, and the booleans, are the values; so are the numbers that are single, for the functions whose result is a function of the value: `number(s)` for `"1"` and `"2.5"` is `number in 1, 2.5`, and for `"1"` and `"x"` is `number = 1 | Null`. The text of a number (`string(n)`) is not: it is how the number is written (`1` and `1.0`), which a set of numbers does not say, so it is a `string`.
- **The kind, and what the types say of the rest.** A number is itself for `number`, a date for `date`; the date of a date and time is a date and its time a time; a string is a value of the kind or `null`, since a string that is not of that kind can exist; and a number outside what a date or a time takes (a month 13, a second 60, a day past the month) is `null`.

`Null` is among the alternatives only if some arguments give it: a `null`, an argument of another kind, a list that does not have exactly one item (a list of one is its item, section 10.3.2.9.4), a string that is not of the kind, and arguments of the right kinds that the function rejects.

| Expression | Type | Warnings |
| --- | --- | --- |
| `number(k)` | `number` | — |
| `number(s)` | `number \| Null` | — |
| `string(k)` | `string` | — |
| `string(b)` | `string in {"false", "true"} \| Null` | — |
| `date(dt)` | `date \| Null` | — |
| `time(dtr)` | `time \| Null` | — |
| `date(s)` | `date \| Null` | — |
| `duration(s)` | `years and months duration \| days and time duration \| Null` | — |
| `years and months duration(d, dr)` | `years and months duration \| Null` | — |
| `if n != null then date(2021, 1, n) else null` | `date \| Null` | `null_possible` |
| `if s != null then number(s) else 0` | `number \| Null` | `null_possible` |

Where the name cannot be `null` the `Null` that is left is the conversion's own: `date(dt)` for a date and time that is never `null` is a `date`, and `years and months duration(d, dt)` for two dates is a duration; `date(s)` for a string is a date or `null`. A day, a month, a year, an hour, a minute, a second or an offset is read for its fraction and its range: the fraction of a year, a month, a day and an hour is cut off (`date(2021, 1, 0.5)` is the day `0`), a second is not, and an offset is whole seconds within 14 hours.

## Limits

- The text of a date or a time is not read: a set of dates is not run through `string`, and a string that is not a finite list is `date | Null`.
- A day past the 28th is `null` for a month that does not have it. The sets of the months and the years may have no such month, and the type is then a superset (`date(2021, 12, 31)` is a date, and the rule says it can be `null` when the month is a range).
- The date or the time that a conversion gives has no set of values, except the one that is the argument.

See also: [string](string.md), [number](number.md), [date](date.md), [time](time.md); [type-system.md](../type-system.md), 3.3.
