TypeScript Expert — Series 3

Preview — 3 of 10 questions

javascript
type Concat<A extends readonly unknown[], B extends readonly unknown[]> = [...A, ...B];

type R1 = Concat<[1, 2], [3]>;
type R2 = Concat<[1, 2], number[]>;
type R3 = Concat<number[], [1, 2]>;
AAll three are (1 | 2 | 3 | number)[] — spreading always collapses to an array
BR1 is [1, 2, 3]; R2 and R3 are compile-time errors — you cannot spread a non-tuple
CR1 is [1, 2, 3]; R2 is [1, 2, ...number[]]; R3 is [...number[], 1, 2]
DR1 is [1, 2, 3]; R2 and R3 are both [1, 2, ...number[]]

javascript
type Json =
  | string
  | number
  | boolean
  | null
  | Json[]
  | { [key: string]: Json };

const a: Json = { users: [{ id: 1, tags: ["a"] }, null] };
const b: Json = { at: new Date() };
Aa compiles; b is a compile-time error — Date is not one of Json's constituents
BBoth are compile-time errors — a type alias may not reference itself
CBoth compile — { [key: string]: Json } accepts any object
Da is an error because arrays may not mix object and null members; b compiles

javascript
interface Consumer<out T> {
  consume(value: T): void;
}
ACompiles fine — out is a hint, and TypeScript ignores it when it disagrees
BCompiles fine — out makes Consumer covariant, which parameters support
CCompiles fine, but Consumer<Dog> becomes assignable to Consumer<Animal> unsoundly
DCompile-time error — T is used in a contravariant position, which contradicts the declared out annotation

Sign up free to play

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