Menu

TypeScript Interview Questions and Answers (25 with Code)

25 TypeScript interview questions with short, correct answers and code, grouped from beginner to advanced: any vs unknown, interface vs type, generics, narrowing, utility types, mapped and conditional types, structural typing, tsconfig and TypeScript 7.

This page includes runnable editors - edit, run, and see output instantly.

These are the TypeScript questions interviewers ask most, with the short answer you should be able to give and a small example. They are grouped by level; a junior role usually stops after the first group, and a senior one expects you to write the types in the last group from memory.

Beginner Questions

1. What is TypeScript?

TypeScript is JavaScript with static types, made by Microsoft. You annotate values with types, the compiler checks them, and then it removes the types and outputs plain JavaScript that runs anywhere JavaScript runs.

Without the @ts-expect-error comment, the second call is a compile error, so the bug never ships.

2. Does TypeScript check types at run time?

No. Types are erased during compilation; the output has no trace of them. The run above prints 23 because nothing at run time knows a should be a number. To check data from outside the program (JSON, user input, API responses) you write real checks, such as a type guard or a schema validator.

3. What are the basic types?

string, number (one type for integers and floats; there is no int), boolean, bigint, symbol, null and undefined, plus arrays (number[]), tuples ([string, number]), object types, any, unknown, never and void. Use the lowercase names: String and Number are the wrapper object types.

4. What is the difference between any and unknown?

Both accept any value. any also turns off checking, so any operation compiles. unknown allows nothing until you narrow it, which makes it the safe type for values you have not checked yet.

5. What is type inference?

The compiler works out types you did not write: let count = 0 is a number, const mode = "dark" is the literal type "dark", and a function's return type comes from its return statements. The usual rule is to annotate function parameters and public return types and let inference handle local variables.

6. What is the difference between interface and type?

Both describe object shapes, and a class can implements either. An interface can be reopened and merged (declaration merging) and extends other interfaces. A type alias can name anything: unions, tuples, primitives, mapped and conditional types.

interface User { name: string }
interface User { age: number }       // merged: User has name and age

type Id = string | number;           // only a type alias can be a union
type Pair = [string, number];        // or a tuple
type Admin = User & { role: "admin" };

A common convention is interface for object shapes and type for everything else. The full comparison is on the interface vs type page.

7. What are union and intersection types?

A union A | B is a value that is one of the types; you can only use members common to all of them until you narrow it. An intersection A & B is a value that is both at once, with all the members of each.

type Id = string | number;                 // either
type Timestamped = { createdAt: Date };
type Post = { title: string } & Timestamped; // both: title and createdAt

8. What is the difference between void and never?

void is the return type of a function that returns normally without a useful value. never is the type of something that cannot happen: a function that always throws or loops forever, or a union with every case removed. never is assignable to every type, and no value is assignable to never.

function log(msg: string): void { console.log(msg); }
function fail(msg: string): never { throw new Error(msg); }
type Impossible = string & number; // never

Intermediate Questions

9. What is type narrowing?

Narrowing is the compiler following your checks and refining a type inside each branch. It understands typeof, instanceof, in, equality checks, truthiness and user-defined type guards.

10. What is a user-defined type guard?

A function whose return type is value is T. When it returns true, the caller's variable is narrowed to T. The compiler trusts the function, so its body must really check the value.

interface Cat { meow(): void }

function isCat(value: unknown): value is Cat {
    return (
        typeof value === "object" &&
        value !== null &&
        "meow" in value &&
        typeof value.meow === "function"
    );
}

An assertion function, function assertCat(v: unknown): asserts v is Cat, narrows by throwing instead of returning false.

11. What are generics?

Type parameters that let one function, class or type work with many types while keeping the link between input and output. T is inferred from the arguments, and extends constrains what it can be.

pluck(users, "email") would be a compile error, because "email" is not a keyof the user type.

12. What do keyof and typeof do in a type?

keyof T is the union of T's property names. In a type position, typeof x gives the type of a variable. Together, keyof typeof obj turns an object's keys into a union.

const colors = { red: "#f00", green: "#0f0" };
type Colors = typeof colors;        // { red: string; green: string }
type ColorName = keyof typeof colors; // "red" | "green"

13. What are utility types? Name a few.

Built-in generic types that transform other types. The ones asked about most:

UtilityResult
Partial<T>every property optional
Required<T>every property required
Readonly<T>every property readonly
Pick<T, "a" | "b">only the listed properties
Omit<T, "a">every property except the listed ones
Record<K, V>an object with keys K and values V
Exclude<U, X>, Extract<U, X>remove or keep union members
NonNullable<T>T without null and undefined
ReturnType<F>, Parameters<F>a function's return or parameter types
Awaited<T>the value a promise resolves to

The complete list is on the utility types page.

14. What is a discriminated union?

A union of object types that share a literal "tag" property. Checking the tag narrows the value to one member, and a never check in the default branch makes the compiler report any case you forget.

15. What is the difference between as and satisfies?

value as T is a type assertion: it tells the compiler to treat the value as T and skips most checking. value satisfies T checks the value against T but keeps the value's own, more precise type.

type Theme = { primary: string; secondary: string };

const a = { primary: "#07f" } as Theme;        // compiles: the missing key is not reported
const b = { primary: "#07f" } satisfies Theme; // error TS2741: Property 'secondary' is missing
const c = {} as { name: string };              // compiles; c.name is undefined at run time

Once the object is complete, satisfies also keeps its own inferred type: checked against Record<string, string>, the variable still knows exactly which keys it has, where an annotation would widen it to any string key.

16. What does the ! operator do after a variable?

It is the non-null assertion: el! removes null and undefined from the type. It generates no check, so if the value is actually null, the program crashes where it is used. Prefer ?., ?? or an explicit if.

17. What is the difference between private and #private?

private is enforced only by the compiler; the property is an ordinary property in the JavaScript output. #field is a JavaScript private field, enforced by the runtime.

protected works like private but also allows access from subclasses, and readonly forbids reassignment after construction.

18. What is the difference between an abstract class and an interface?

An interface is only a type: it describes a shape and disappears from the output. An abstract class is a real class that cannot be instantiated; it can hold implemented methods, fields and constructors alongside abstract members that subclasses must implement. A class can implement many interfaces but extend only one class.

abstract class Repository<T> {
    protected items: T[] = [];
    abstract validate(item: T): boolean; // subclasses must implement
    add(item: T): void {                 // shared implementation
        if (this.validate(item)) this.items.push(item);
    }
}

19. What is function overloading in TypeScript?

Several call signatures followed by one implementation whose signature is compatible with all of them. Callers see only the overloads, so each call gets a precise return type.

function parse(value: string): number;
function parse(value: string[]): number[];
function parse(value: string | string[]): number | number[] {
    return Array.isArray(value) ? value.map(Number) : Number(value);
}

const one = parse("4");          // number
const many = parse(["1", "2"]);  // number[]

When the return type does not depend on the argument type, a single signature with a union parameter is simpler.

Advanced Questions

20. What is structural typing?

TypeScript compares types by their shape, not by their name. Any value with the required properties is accepted, even if it was never declared with that type.

The extra color is fine here because pixel is a variable. Passing the object literal directly, show({ x: 3, y: 4, color: "red" }), is an excess property error, a check that applies only to fresh literals. When two types with the same shape must not mix (a UserId and an OrderId that are both strings), use a branded type: type UserId = string & { readonly __brand: "UserId" }.

21. How would you implement Readonly and Partial yourself?

With mapped types: iterate over keyof T and add a modifier to each property.

type MyReadonly<T> = { readonly [K in keyof T]: T[K] };
type MyPartial<T> = { [K in keyof T]?: T[K] };
type Mutable<T> = { -readonly [K in keyof T]: T[K] }; // "-" removes a modifier

type User = { name: string; age: number };
type Draft = MyPartial<User>; // { name?: string; age?: number }

22. What are conditional types and infer?

T extends U ? X : Y picks a type based on a condition. Inside the condition, infer declares a type variable that captures part of the matched type. Conditional types distribute over unions.

type MyReturnType<F> = F extends (...args: any[]) => infer R ? R : never;
type ElementOf<T> = T extends (infer E)[] ? E : T;

type A = MyReturnType<() => Promise<number>>; // Promise<number>
type B = ElementOf<string[]>;                 // string
type C = ElementOf<number | boolean[]>;       // number | boolean (distributed)

More patterns are on the conditional types page.

23. What is a .d.ts file, and what does declare do?

A declaration file holds only types for code that exists elsewhere, such as a JavaScript library or browser APIs. declare states that a value exists without creating it: declare const VERSION: string; compiles to nothing. Library types come bundled with the package or from @types/{name} packages, and tsc generates .d.ts files for your own code with declaration: true.

24. What does strict do, and which tsconfig options matter most?

"strict": true turns on noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables and strictBuiltinIteratorReturn. In TypeScript 7 it is on by default. The other options interviewers ask about:

OptionAnswer in one line
targetwhich JavaScript version the output uses
modulethe output module format: nodenext follows Node's rules, esnext/preserve keep import for a bundler
moduleResolutionhow imports are found: nodenext wants ./file.js in ES module files, bundler accepts ./file
noUncheckedIndexedAccessarr[i] includes undefined in its type
pathsimport aliases for the type checker only; the output keeps the alias, so a bundler or Node's imports field must resolve it
skipLibCheckskip checking .d.ts files, for speed
verbatimModuleSyntaximports used only as types must be marked type; other imports are kept as written

25. What is TypeScript 7?

The TypeScript compiler rewritten in Go as a native program, released as version 7 of the typescript npm package. The command is still tsc and the language is the same, but it is much faster than the JavaScript-based 6.x compiler: the TypeScript team reports speedups of 8x to 12x on typical full builds, from native code and shared-memory multithreading. It also enforces removals that 6.0 had deprecated; for example baseUrl, outFile, moduleResolution: "node10", module: "amd" and alwaysStrict: false are now errors (TS5102, TS5108) that tell you to remove them.

Frequently Asked Questions

What are the most common TypeScript interview questions?

The ones that come up most: the difference between any and unknown, interface vs type, how generics work, how narrowing and type guards work, what utility types like Partial, Pick and Omit do, and whether TypeScript checks types at run time (it does not).

What TypeScript questions are asked for senior developers?

Expect to write types, not only read them: implement Readonly or ReturnType with mapped and conditional types, explain structural typing and when to use branded types, design a discriminated union with an exhaustive check, and discuss tsconfig choices such as strict, noUncheckedIndexedAccess and module resolution.

How do I prepare for a TypeScript interview?

Write small programs with strict on and read the compiler errors until you can predict them. Be able to explain narrowing, generics with constraints, the main utility types, and why type assertions are unsafe, each with a two-line example.

Is TypeScript asked in React and Angular interviews?

Usually. Angular itself is written in TypeScript and Angular apps are written in it, so Angular interviews tend to assume it, including decorators such as @Component and access modifiers. React interviews for a TypeScript codebase often ask you to type props, state and event handlers, which uses the same interfaces, unions and generics shown here.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED