All quizzesHard
Type-Level Generics
Preview — 3 of 10 questions
How does this type work?
javascript
type UnionToIntersection<U> =
(U extends any ? (x: U) => void : never) extends (x: infer I) => void
? I
: never;
type U = { a: string } | { b: number } | { c: boolean };
type I = UnionToIntersection<U>;
// I = ?A{ a: string } | { b: number } | { c: boolean } — unchanged
B{ a: string } & { b: number } & { c: boolean } — the intersection
Cnever — union-to-intersection is impossible
D{ a: string; b: number; c: boolean } — merged into one flat object
What does this type achieve?
javascript
type DeepReadonly<T> = T extends (infer U)[]
? ReadonlyArray<DeepReadonly<U>>
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;
interface Config {
server: { host: string; ports: number[] };
features: { [key: string]: boolean };
}
type ImmutableConfig = DeepReadonly<Config>;AMakes all properties and nested properties readonly recursively — including array elements
BMakes only top-level properties readonly
CEquivalent to Readonly<Config>
DProduces never for complex types
What's the type issue with native Object.entries?
javascript
const user = { id: "1", name: "Alice", age: 30 };
// Native Object.entries:
const entries1 = Object.entries(user);
// entries1: [string, string | number][] ← ?
// Type-safe version:
type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T];
function entries<T extends object>(obj: T): Entries<T>[] {
return Object.entries(obj) as Entries<T>[];
}
const entries2 = entries(user);
// entries2: ["id", string] | ["name", string] | ["age", number]ABoth are equivalent — TypeScript handles Object.entries perfectly
BThe generic version is wrong — it returns a union not an array
CNative Object.entries uses a widened type [string, string | number][]; the generic version preserves each key-value pair as a discriminated tuple
DObject.entries can only be typed with any
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.