Typescript Type-level playground
This project is a playground of type-level operations for TypeScript.
npm i type-ts
The stable version is tested against TypeScript 3.1.6+.
Returns true
if A
extends from B
, false
otherwise.
Extends<'foo', string> // true
Extends<string, number> // false
Returns true
if A
and B
are equal types, false
otherwise.
Equals<string, string> // true
Equals<string, number> // false
Returns true
if A
and B
are equal types to true
, false
otherwise.
And<true, true> // true
And<true, false> // false
Returns true
if either A
or B
are true
, false
otherwise.
Or<false, true> // true
Or<false, false> // false
Returns true
if A
and B
differ, one is true
and the other is false
. false
otherwise.
Xor<false, true> // true
Xor<true, true> // false
Returns true
if A
is false
. false
otherwise.
Not<false> // true
Not<true> // false
Returns T
if C
is true
. E
otherwise.
If<true, number, string> // number
If<false, number, string> // string
Same representation, different type for the typesystem.
type USD = Newtype<number, "USD">;
type EUR = Newtype<number, "EUR">;
const usd = 10 as USD;
const eur = 10 as EUR;
function gross(net: USD, tax: USD): USD {
return (net + tax) as USD; // We can treat them like the underlying type
}
gross(usd, usd); // $ExpectType Newtype<number, "USD">
// $ExpectError
gross(eur, usd); // Type '"EUR"' is not assignable to type '"USD"'.
// $ExpectError
gross(1, 1.2); // Type 'number' is not assignable to type '"USD"'.
Extracts a super-type of A
identified by its keys K
.
Omit<{ a: string; b: number }, 'a'> // { b: number }
Overwrites A
with the properties in B
.
Overwrite<{ a: string; b: number }, { b: boolean }> // { a: string; b: boolean }
Make the specified properties K
partial in type A
.
Diff<{ a: string; b: number }, 'b'> // { a: string; b?: number }
Encodes the constraint that a given object A
does not contain specific keys K
declare function f(x: Lacks<{ a: string; b: number }, "a">): void;
// $ExpectError
f({ a: "foo", b: 1 });
Encodes that A
cannot have extra propeties.
type E = Exact<{ a: string; b: number }>;
declare function f(a: E): void;
declare const x: { a: string };
declare const y: { a: string; b: number };
declare const z: { a: string; b: number; c: boolean };
f(x); // $ExpectError
f(y); // Ok
f(z); // $ExpectError
Picks from A
only the keys of a certain type B
.
KeysOfType<{a: string, b: string | boolean, c: boolean, d: string}, string> // "a" | "d"
Recursively sets modifiers readonly
and ?
.
interface A {
b: {
c: string;
d: Array<{ e: number }>;
};
}
type ReadonlyA = DeepReadonly<A>;
declare const a: ReadonlyA;
a.b.d[1].e = 1; // $ExpectError
Extracts from A
only the properties found on B
.
Intersection<{ a: number; b: number }, { b: number; c: number }> // { b: number }
Returns the union of all value types from A
.
ValuesOf<{ a: number; b: boolean; c: string; d: number }> // number | boolean | string
Intersection of the literal union sets A
and B
.
SetIntersection<"a" | "b", "c" | "d"> // never
SetIntersection<"a" | "b", "b" | "c"> // "b"
SetIntersection<"a" | "b" |Â "c" , "b" | "c"> // "b" | "c"
Difference of the literal union sets A
and B
.
SetDifference<"a" | "b", "c"> // "a" | "b"
SetDifference<"a" | "b", "b"> // "a"
Union of the literal union sets A
and B
.
SetUnion<"a" | "b", "b" | "c"> // "a" | "b" | "c"
Display purpouse only. Useful when dealing with complex types and want to see something simpler in the IDE.
Pretty<{ a: 1 } & { b: 2 }> // { a: 1, b: 2 }
Use to prevent a usage of type T
from being inferred in other generics. See
Represents JSON representable types.
Unwraps nested Promise
s. Typescript does not collapse nested promises. See
type x = Awaited<number>; // Promise<number>
type y = Awaited<Promise<Promise<Promise<string>>>>; // Promise<string>
type z = Awaited<Awaited<Awaited<boolean>>>; // Promise<boolean>
Peano numbers implementation.
Zero
Succ<Zero> // _1
Predefined aliases.
Add<_4, _3> // _7
Add<_5, _4> // _9
Substract<_0, _1> // never
Substract<_4, _3> // _1
Substract<_5, _2> // _3
Multiply<_2, _3> // _6
Multiply<_3, _3> // _9
Quotient<_4, _0> // never
Quotient<_3, _3> // _1
Quotient<_0, _6> // _0
Quotient<_4, _2> // _2
Quotient<_6, _5> // _1
Quotient<_3, _3> // _0
Quotient<_5, _3> // _2
Quotient<_4, _2> // _0
Quotient<_6, _5> // _1
GreaterThan<_1, _0> // true
GreaterThan<_5, _2> // true
GreaterThan<_0, _0> // false
GreaterThan<_0, _1> // false
LowerThan<_1, _0> // false
LowerThan<_5, _2> // false
LowerThan<_0, _0> // false
LowerThan<_0, _1> // true
EqualsTo<_0, _1> // false
EqualsTo<_2, _2> // true
Convert a number
to a Nat
. Do not use with negative numbers.
AsNat<2> // _2 or Succ<Succ<_0>>
Convert a Nat
to a number
.
AsNumber<_2> // 2
Non empty tuple.
Empty tuple.
Compile time arrays (aka array literals).
Alias for StaticArray<any>
.
Returns the first type of the static array.
Head<[]> // never
Head<[1, 2, 3]> // 1
Head<[number, 2, 3]> // number
Tail of the static array.
Tail<[]> // never
Tail<[1, 2]> // [2]
Tail<[1, 2, 3]> // [2, 3]
Returns the last type of the static array.
Last<[]> // never
Last<[1, 2]> // 2
Last<[1, 2, 3]> // 3
Adds a type to the front of the static array.
Cons<1, []> // [1]
Cons<1, Cons<2, []>> // [1, 2]
Cons<1, [2, 3]> // [1, 2, 3]
Drops N
elements from the front of the static array.
Drop<[], _2> // []
Drop<[1, 2], _1> // [2]
Drop<[1, 2, 3], _2> // [3]
Reverses a static array.
Reverse<[]> // []
Reverse<[1, 2]> // [2, 1]
Reverse<[1, 2, 3]> // [3, 2, 1]
Return the first N
types of the static array.
Take<[], _2> // []
Take<[1, 2], _1> // [1]
Take<[1, 2, 3], _2> // [1, 2]
Concatenates two static arrays.
Concat<[], []> // []
Concat<[], [1]> // [1]
Concat<[2], [1]> // [2, 1]
Concat<[1, 2], [3]> // [1, 2, 3]
Concat<[1], [2, 3]> // [1, 2, 3]
Zips two static arrays into one with length equals to the shortest length where at each position there is a tuple with the types of each one of them.
Zip<[], []> // []
Zip<[], [1]> // []
Zip<[2], [1]> // [[2, 1]]
Zip<[1, 2], [3]> // [[1, 3]]
Zip<[1], [2, 3]> // [[1, 2]]
Zip<[1, 2], [3, 4]> // [[1, 3], [2, 4]]
Returns a static array of length N
with A
in each position.
Repeat<0, _0> // []
Repeat<0, _1> // [0]
Repeat<0, _2> // [0, 0]
Repeat<0, _3> // [0, 0, 0]
Returns the length of a static array.
Length<[]> // 0
Length<[1]> // 1>
Length<[1, 2]> // 2
Length<[1, 2, 3]> // 3
type _10 = Add<_9, _1>;
type _20 = Multiply<_10, _2>;
Length<Repeat<0, _20>> // 20
Same as Length
but returns a Nat
instead.
LengthN<[]> // _0
LengthN<[1]> // _1
LengthN<[1, 2]> // _2
LengthN<[1, 2, 3]> // _3
LengthN<Repeat<0, _20>> // _20
Adds a type to the end of a static array.
Push<1, []> // [1]
Push<1, Cons<2, []>> // [2, 1]
Push<1, [3, 2]> // [3, 2, 1]
Type-level version of this operations.
declare module "type-ts/list" {
interface Map1<A = unknown> {
AsNat: A extends number ? AsNat<A> : never;
}
interface Reduce2<A = unknown, B = unknown> {
Add: A extends Nat ? (B extends Nat ? Add<A, B> : never) : never;
}
}
Map<[0, 1, 2], "AsNat"> // [_0, _1, _2]
Reduce<[_1, _2, _3] "Add", _0> // _6