Advanced Type Engineering — Series 2

Preview — 3 of 10 questions

javascript
interface ApiResponse {
  data: string;
  error: string;
  status: number;
}
type ResponseValues = ApiResponse['data' | 'error'];
AResponseValues is a tuple [string, string], pairing both property types together
BCompile-time error — indexed access types only accept a single key, never a union of keys
CResponseValues is string — indexing with a union of keys retrieves the union of the corresponding property types (string | string), which simplifies to plain string
DResponseValues is ApiResponse, unchanged

javascript
type DeepElement<T> = T extends (infer U)[] ? DeepElement<U> : T;
type A = DeepElement<number[][][]>;
type B = DeepElement<string>;
AA is number[][], and B is string
BCompile-time error — a recursive type alias can't use infer inside its own definition
CA is number[][][], unchanged, and B is never
DA is number, and B is string — the recursive conditional type keeps unwrapping one array layer at a time until it reaches a type that isn't an array at all

javascript
interface User {
  id: number;
  name: string;
  password: string;
}
type PublicUser = { [K in keyof User as K extends 'password' ? never : K]: User[K] };
const u: PublicUser = { id: 1, name: 'Ana' };
APublicUser drops the password key entirely — remapping a key to never inside the mapped type's as clause causes that property to be omitted from the resulting type, so u (correctly missing password) compiles fine
BCompile-time error — mapping a key to never inside an as clause isn't valid syntax
CPublicUser retains all of User's properties, including password
DPublicUser keeps the password key, but its value type becomes never

Sign up free to play

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