Typescript is a typed superset of Javascript. For this challenge, we'll consider the following classic basic types:
string
number
boolean
undefined
null
And two "meta" types:
any
never
The type any
annotates that any type is valid:
const a: any = "foo";
const b: any = 42;
const c: any = true;
const d: any = undefined;
Whereas never
annotates that no type is valid:
const e: never = <no valid literal assignment possible>;
We'll also consider two compositions of types: unions and intersections, annotated as |
and &
respectively.
A union type expects either one or the other type:
const f: string | number = "foo";
const g: string | number = 42;
While an intersection creates a combination of both types:
const h: string & any = "foo";
const i: string & any = 42;
const j: string & number = <no valid literal assignment possible>;
The order of operands within unions and intersections doesn't matter, string | number
is equal to number | string
.
The challenge
Given one of the above type declarations, return the resulting resolved type. The input will be one of the following:
- a basic type as listed above or;
- a meta type as listed above or;
- a union of two basic and/or meta types or;
- an intersection of two basic and/or meta types.
Examples
// All basic and meta types simply map to themselves
string → string
number → number
any → any
never → never
// Unions between basic types create unions except with themselves
string | number → string | number
string | undefined → string | undefined
string | string → string
// Intersections between basic types create never except with themselves
string & number → never
string & undefined → never
string & string → string
// Unions with any create any
any | string → any
any | never → any
// Intersections with any result in any except with never
any & string → any
any & number → any
any & never → never
// Unions with never yield the other half
never | string → string
never | any → any
never | never → never
// Intersections with never return never
never & string → never
never & any → never
never & never → never
A good way to get a feel for the types is to try out the Typescript playground.
Any reasonable and consistent input-output format, standard loop holes, code-golf.
any & something
not givesomething
? I would imagine anumber
is not bothany
andstring
\$\endgroup\$const x: { foo: string } & { bar: number } = { foo: "foo", bar: 42 };
. \$\endgroup\$any
is not the type that annotates that any type is valid;unknown
is. Rather,any
is a non-type that’s used for interoperability with untyped JavaScript, behaving contradictorily as both a subtype and supertype of every type. This is whyany & string
isany
, whileunknown & string
isstring
as you’d expect.any
should not be used in typed code, whileunknown
is safe. \$\endgroup\$