Skip to content
TypeScript ts interview 4 min read

Output-Based Questions

Output-based questions hand you a code snippet and ask one of three things: what type does the compiler infer, what error does it raise, or what does the program print at runtime. They test whether you can run the type checker in your head and remember that types are erased before execution. For each snippet below, try to answer before reading the explanation — the goal is to predict TypeScript’s behavior precisely, not approximately.

What type is inferred?

What is the type of result?

const result = [1, 2, 3].map((n) => n.toString());

Answer: string[]. The array literal is inferred as number[], the callback parameter n is contextually typed as number, and n.toString() returns string, so map produces string[].

What is the type of x?

const x = { a: 1, b: "two" } as const;

Answer: { readonly a: 1; readonly b: "two" }. as const makes every property readonly and narrows each value to its literal type instead of number/string.

What is the type of value inside the guard?

function f(value: string | number) {
  if (typeof value === "string") {
    return value; // <-- here
  }
  return value;   // <-- and here
}

Answer: Inside the if, value is string. After it, the remaining type is number. typeof narrowing splits the union across the two branches.

What is the return type of wrap?

function wrap<T>(items: T[]) {
  return { items, count: items.length };
}
const r = wrap(["a", "b"]);

Answer: { items: string[]; count: number }. T is inferred as string from the argument, so the returned object’s items is string[].

What error does the compiler raise?

Does this compile?

interface Box { value: number; }
const b: Box = { value: 1, extra: 2 };

Answer: Error. Excess property check on the fresh literal: Object literal may only specify known properties, and 'extra' does not exist in type 'Box'.

Does this compile?

let u: unknown = getData();
u.toUpperCase();

Answer: Error: 'u' is of type 'unknown'. You must narrow unknown (e.g. typeof u === "string") before accessing members.

Does this compile?

const arr: readonly number[] = [1, 2, 3];
arr.push(4);

Answer: Error: Property 'push' does not exist on type 'readonly number[]'. Mutating methods are removed from readonly arrays.

Does this compile?

enum Color { Red, Green, Blue }
const c: Color = 5;

Answer: No error. Numeric enums accept any number assignment by design, even values outside the declared members. String enums do not have this loophole.

Does this compile?

type A = { kind: "a"; x: number };
type B = { kind: "b"; y: number };
function handle(v: A | B) {
  return v.x;
}

Answer: Error: Property 'x' does not exist on type 'A | B' (it is missing on B). You must narrow on v.kind first.

What does it print at runtime?

What is logged?

const value: string = "5" as any as number as unknown as string;
console.log(typeof value);

Answer: string. Type assertions are erased at compile time — they change nothing at runtime. The variable still holds the string "5".

What is logged?

enum E { A = "x", B = "y" }
console.log(Object.keys(E).length);

Answer: 2. String enums produce a one-way object { A: "x", B: "y" }, so two keys. A numeric enum would reverse-map and print 4.

What is logged?

function greet(name: string = "World") {
  console.log(`Hello, ${name}`);
}
greet(undefined);

Answer: Hello, World. Passing undefined triggers the default parameter; null would not.

What is logged?

class Counter {
  private count = 0;
  increment = () => ++this.count;
}
const c = new Counter();
console.log(c.increment(), c.increment());

Answer: 1 2. private is a compile-time-only modifier; the arrow-function field still increments the runtime value normally.

What is logged?

const obj = { a: 1 } as { a: number; b: number };
console.log(obj.b);

Answer: undefined. The assertion lies to the compiler — b was never assigned — so the runtime read yields undefined even though the type says number.

The recurring lesson: every type construct (as, private, annotations, enum const) is checked at compile time but enum and class fields still emit real JavaScript. When asked “what prints”, reason about the emitted JS, not the types.

Best Practices

  • State whether the question is about a type, an error, or runtime output before answering.
  • Remember type assertions and annotations vanish at runtime — they never change behavior.
  • Recall the numeric-enum quirk: reverse mapping doubles Object.keys length.
  • Watch for excess property checks on fresh literals versus assigned variables.
  • For readonly arrays, note that mutating methods are removed from the type.
  • Default parameters fire for undefined but not null.
  • Mentally “compile then run” — separate the type pass from the JavaScript output.
Last updated June 29, 2026
Was this helpful?