Type-Level Computation — Series 2

Preview — 3 of 10 questions

javascript
type BuildTuple<N extends number, Acc extends unknown[] = []> = Acc['length'] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>;
type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest] ? Rest['length'] : never;
type Result = Subtract<7, 3>;
AResult is 10, the sum instead of the difference
BResult is the general type number, since precise arithmetic can't be represented at the type level
CResult is 4 — subtraction is simulated by building two tuples of lengths A and B, then checking whether the longer tuple (BuildTuple<A>) starts with all of the shorter tuple's elements (BuildTuple<B>), capturing whatever remains via a rest pattern and reading that remainder's length
DCompile-time error — [...BuildTuple<B>, ...infer Rest] combines two rest-like patterns, which isn't valid tuple destructuring

javascript
type Get<T, Path extends string> = Path extends `${infer Key}.${infer Rest}`
  ? Key extends keyof T ? Get<T[Key], Rest> : never
  : Path extends keyof T ? T[Path] : never;
interface Data { user: { profile: { name: string } } }
type NameType = Get<Data, 'user.profile.name'>;
ANameType is Data['user'], resolving only the first path segment
BNameType is never, since template literal patterns can't be combined with keyof checks
CCompile-time error — a recursive type alias can't reference a generic type parameter (T) whose value changes at each recursive step
DNameType is string — the recursive conditional type walks the dot-separated path one segment at a time, indexing progressively deeper into the object type at each step, until the final segment resolves to a concrete property type

javascript
type XOR<T, U> = T extends U ? (U extends T ? never : T | U) : T | U;
type Same = XOR<'a', 'a'>;
type Different = XOR<'a', 'b'>;
ASame is never, and Different is 'a' | 'b' — when T and U are the exact same type, both directions of the mutual extends check succeed, triggering the inner never branch; when they're different, unrelated literal types, the very first check already fails, falling through directly to the union of both
BBoth Same and Different resolve to never
CBoth Same and Different resolve to 'a' | 'b'
DCompile-time error — a nested conditional type's inner branch can't reference both of the outer conditional's type parameters

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.