38 questions - Beginner to intermediate

TypeScript interview questions and answers

TypeScript questions come up in almost every Angular interview and most React ones. Interviewers want to see that you use types to catch real bugs, not that you memorised syntax. Keep answers concrete.

TypeScript basics

What is TypeScript?

TypeScript is JavaScript with a type system added on top. You write types, the compiler checks them, and then the types are removed - the browser runs plain JavaScript. The whole benefit happens before the code runs.

Why use TypeScript instead of JavaScript?

It catches typos and wrong shapes at compile time instead of in production, gives real autocomplete and safe renaming in the editor, and acts as documentation that cannot go out of date. On a large team that saves a lot of time.

What is type inference?

TypeScript works out the type by itself from the value you assign, so you do not have to annotate everything. Annotate function parameters and public return types; let inference handle simple local variables.

let count = 5;        // inferred as number
count = "five";       // Error

What is the difference between any, unknown and never?

any turns all checking off and should be a last resort. unknown is the safe version: you can hold anything in it but you must narrow the type before using it. never means a value that can never happen, like the return type of a function that always throws.

let a: any = 1; a.foo();          // allowed, may crash
let u: unknown = 1;
// u.toFixed();                    // Error
if (typeof u === "number") u.toFixed(); // fine

What is the difference between null, undefined and strictNullChecks?

With strictNullChecks on, null and undefined are not allowed in a normal type, so you must say string | null and then check before use. That single flag prevents most "cannot read property of undefined" crashes.

What is a union type and an intersection type?

A union with | means the value is one of these types. An intersection with & means the value has all of these types combined.

type Status = "idle" | "loading" | "error";
type Admin = User & { permissions: string[] };

What is a literal type?

A type whose only allowed value is one exact value, like "GET". Combined into a union it gives you a safe set of options, which is usually better than an enum.

What is the difference between an enum and a union of literals?

An enum produces real JavaScript code at runtime and adds to the bundle. A union of string literals disappears at compile time and is easier to work with. Use const enum or a plain union unless you truly need the runtime object.

What is a tuple?

An array with a fixed length where each position has its own type. React useState returns a tuple: a value and a setter.

const point: [number, number] = [10, 20];
const pair: [string, boolean] = ["ok", true];

What are optional and readonly properties?

A question mark makes a property optional, so it may be missing. readonly stops assignment after the object is created. Both are compile-time only.

interface User {
  id: number;
  readonly createdAt: string;
  nickname?: string;
}

Types, interfaces and structure

What is the difference between type and interface?

Both describe the shape of an object. An interface can be reopened and added to later (declaration merging) and is the usual choice for public object shapes and classes. A type alias can also describe unions, tuples and mapped types, which an interface cannot. Pick one style and stay consistent.

interface Props { title: string; }
interface Props { subtitle?: string; }   // merged, both exist

type Id = string | number;               // interface cannot do this

What is structural typing?

TypeScript compares the shape of types, not their names. If an object has all the required properties with the right types, it fits - it does not have to declare that it implements anything.

What is excess property checking?

When you assign an object literal directly, TypeScript complains about extra properties that are not in the type, to catch typos. Assigning through a variable first skips that check, because then it is only checking compatibility.

What are generics?

Generics let a function or type work with any type while keeping the relationship between input and output. The caller decides the concrete type, so you keep safety without repeating code.

function first<T>(items: T[]): T | undefined {
  return items[0];
}
const n = first([1, 2, 3]);      // number | undefined
const s = first(["a", "b"]);     // string | undefined

What is a generic constraint?

It limits what the generic type can be, using extends. That lets you safely use properties inside the function.

function getLength<T extends { length: number }>(x: T) {
  return x.length;
}

What is keyof and typeof in the type world?

keyof gives a union of the property names of a type. typeof in a type position takes the type of an existing value. Together they let you write code that stays correct when the object changes.

const config = { host: "localhost", port: 8080 };
type Config = typeof config;          // { host: string; port: number }
type Key = keyof Config;              // "host" | "port"

function get<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

What are the common utility types?

Partial makes everything optional, Required does the opposite, Pick keeps chosen keys, Omit removes keys, Record builds a key-value map, Readonly locks properties, and ReturnType extracts the return type of a function.

type Draft = Partial<User>;
type Preview = Pick<User, "id" | "name">;
type Safe = Omit<User, "password">;
type Lookup = Record<string, User>;

What is a mapped type?

A type that builds a new type by looping over the keys of another one. Partial and Readonly are written this way internally.

type Nullable<T> = { [K in keyof T]: T[K] | null };

What is a conditional type?

A type that chooses between two types based on a check, using the extends ? : form. It is how helpers like ReturnType are built.

type Unwrap<T> = T extends Promise<infer U> ? U : T;
type A = Unwrap<Promise<string>>; // string

What does infer do?

Inside a conditional type, infer captures a piece of the type into a new name so you can return it. It is how you pull the element type out of an array or the value out of a promise.

Narrowing, safety and classes

What is type narrowing?

It is TypeScript reducing a union to a smaller type after a check. typeof, instanceof, the in operator, a truthy check or comparing a literal field all narrow.

function print(value: string | number) {
  if (typeof value === "string") {
    value.toUpperCase();  // string here
  } else {
    value.toFixed(2);     // number here
  }
}

What is a discriminated union?

A union of object types that all share one literal field, usually called kind or type. Checking that field narrows to exactly one member. It is the cleanest way to model API responses and Redux actions.

type Result =
  | { status: "success"; data: User }
  | { status: "error"; message: string };

function show(r: Result) {
  if (r.status === "success") return r.data.name;
  return r.message;
}

What is a type guard function?

A function whose return type is written as "value is Type". When it returns true, TypeScript narrows the variable in the calling code. Useful for validating data that came from an API.

function isUser(x: unknown): x is User {
  return typeof x === "object" && x !== null && "id" in x;
}

What is a type assertion and why is it risky?

Writing "as Type" tells the compiler to trust you. Nothing is checked at runtime, so if the data does not actually match, the crash happens later and further away. Prefer narrowing or a validation library.

What does the non-null assertion operator (!) do?

It tells the compiler a value is definitely not null or undefined. Like as, it is unchecked, so use it only when you can prove it, for example right after an explicit guard.

What are access modifiers in a TypeScript class?

public is the default and visible everywhere. private is visible only inside the class and is enforced at compile time only. protected is visible in the class and its subclasses. The JavaScript # private field is enforced at runtime as well.

What is an abstract class?

A class you cannot instantiate directly. It can define some working methods and leave others abstract for subclasses to implement. Use it when several classes share real code; use an interface when you only need a contract.

What is a decorator?

A function that adds behaviour or metadata to a class, method or property using @ syntax. Angular is built on decorators such as @Component, @Injectable and @Input.

@Component({ selector: "app-user" })
export class UserComponent {
  @Input() userId!: string;
}

What is declaration merging?

Two declarations with the same name can be combined. Two interfaces merge into one, and a namespace can add to a class or function. It is how libraries extend types like the Express Request object.

What is a .d.ts file?

A declaration file that describes the types of JavaScript code without containing any implementation. It is how you add types to an untyped library, either from DefinitelyTyped as @types/name or written yourself.

Config and real projects

What is tsconfig.json?

The configuration file that tells the compiler which files to include, which JavaScript version to output, which module system to use and how strict to be. It is the first file to check when a build behaves oddly.

What does strict: true turn on?

A group of flags including strictNullChecks, noImplicitAny, strictFunctionTypes and strictPropertyInitialization. Turning it on for a new project is standard advice; on an old project turn the flags on one at a time.

What does noImplicitAny do?

It makes the compiler complain when it cannot infer a type and would otherwise silently use any - most often on function parameters. It is the single most valuable strict flag.

Does TypeScript check types at runtime?

No. Everything is erased during compilation. If data comes from an API or a form, you still need a runtime check, either written by hand or with a validation library such as Zod.

What is the difference between a compile-time error and a runtime error here?

A compile-time error is TypeScript refusing to build because the types do not fit; nothing has run yet. A runtime error happens in the browser. TypeScript only helps with the first kind, which is why input validation still matters.

What is the satisfies operator?

It checks that a value matches a type without widening the value to that type, so you keep the precise inferred literal types and still get the error checking.

const routes = {
  home: "/",
  blog: "/blog",
} satisfies Record<string, string>;
// routes.home is "/" not just string

How do you type an async function?

The return type is a Promise of the resolved value. TypeScript infers it, but writing it makes the contract clear.

async function getUser(id: string): Promise<User | null> {
  const res = await fetch("/api/users/" + id);
  return res.ok ? ((await res.json()) as User) : null;
}

How do you migrate a JavaScript project to TypeScript?

Add TypeScript with allowJs so both file types build, rename files a few at a time starting with shared utilities, add types where they help most, turn on strict flags one by one, and avoid a big-bang rewrite.

Continue with another topic

Practise live

CrackInterviewAI listens to the live interview and gives a structured answer on screen for coding, system design, HR and project questions. Download for Windows.