Skip to content

Instantly share code, notes, and snippets.

@tlkahn
Created July 18, 2024 06:07
Show Gist options
  • Save tlkahn/1d9ddc150c935d73854dea193b77edcc to your computer and use it in GitHub Desktop.
Save tlkahn/1d9ddc150c935d73854dea193b77edcc to your computer and use it in GitHub Desktop.
typescript koan
// Literal type
type Drinks = 'Coke' | 'Milk' | 'Water' | 'Coffee';
type UnUnite<T, K> = T extends K ? never : T;
type Result = UnUnite<string | number | boolean, string>; // Result: number | boolean
type HealthDrinks = UnUnite<Drinks, 'Coke'>;
// `infer`
// "destructuring type". "Pattern matching"
type Flip<T> = T extends [infer A, infer B] ? [B, A] : T;
type _1 = Flip<[number, boolean]>;
type Args<T> = T extends (...a: infer A) => infer _ ? A : never;
type UnionFromTuple<T> = T extends [...a: infer A] ? A : T;
type UnionFromTuple2<T> = T extends readonly any[] ? T[number] : never;
type UnionFromTuple3<T> = T extends readonly (infer U)[] ? U : never;
const mytuple = ['hello', 'world'] as const;
type uft = UnionFromTuple<typeof mytuple>;
type uft2 = UnionFromTuple2<typeof mytuple>;
type uft3 = UnionFromTuple3<typeof mytuple>;
type Xs1 = Args<typeof Math.pow>;
type Xs2 = Args<typeof document.getElementById>;
type Head<T> = T extends [infer H, ...infer _] ? H : never;
type Rest<T> = T extends [infer _, ...infer Rest /* or ...a: infer Rest */]
? Rest
: never;
type Rest2<T> = T extends [infer _, ...a: infer R] ? R : never;
type Rest3<T> = T extends [infer _, ...infer R] ? R : never;
type One = Head<[1, 2, 3]>;
type AfterOne = Rest<[1, 2, 3]>;
type AfterOne2 = Rest2<[1, 2, 3]>;
type AfterOne3 = Rest3<[1, 2, 3]>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment