Skip to content

Instantly share code, notes, and snippets.

@miyaokamarina
Created June 7, 2019 08:30
Show Gist options
  • Save miyaokamarina/ce1ef6f8b024b200e760bf81de421334 to your computer and use it in GitHub Desktop.
Save miyaokamarina/ce1ef6f8b024b200e760bf81de421334 to your computer and use it in GitHub Desktop.
Almost type-safe `path` function for TypeScript
type Falsy = '' | 0n | 0 | false | null | undefined | void;
type If<c, t, f> = c extends Falsy ? f : t;
type Cast<a, b> = a extends b ? a : b;
type Size<t> = t extends readonly any[] ? t['length'] : never;
type Head<t> = t extends readonly [any, ...any[]] ? t[0] : never;
type Last<t> = t extends readonly any[] ? t[Size<Tail<t>>] : never;
type Init<t, x = readonly []> = { 0: Init<Tail<t>, Append<x, Head<t>>>; 1: x }[If<Size<Tail<t>>, 0, 1>];
type Append<t, e> = Concat<t, readonly [e]>;
type Reverse<t, x = readonly []> = { 0: Reverse<Tail<t>, Prepend<Head<t>, x>>; 1: x }[If<Size<t>, 0, 1>];
type Concat<a, b> = Reverse<Reverse<a> extends infer c ? Cast<c, readonly any[]> : never, b>;
type Tail<t> = t extends readonly any[]
? (((...t: t) => any) extends ((h: any, ...t: infer t) => any) ? Readonly<t> : readonly [])
: never;
type Prepend<e, t> = t extends readonly any[]
? (((e: e, ...t: t) => any) extends ((...t: infer t) => any) ? Readonly<t> : Readonly<t>)
: never;
type Path<p, q, r = p, s = q> = {
0: s extends { [t in Head<r>]: infer u } ? Path<p, q, Tail<r>, u> : never;
1: s;
}[If<Size<r>, 0, 1>];
declare const path: <a extends readonly any[]>(...as: a) => Path<Init<a>, Last<a>>;
const o = {
a: {
b: {
c: {
d: {
e: 'Ты пидор.',
},
},
},
},
} as const;
//
const a = path('a', 'b', 'c', 'd', 'e', o);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment