{}const=>[]async()letfn</>var
DevelopmentCareerWeb

The most common questions in a TypeScript interview

Are you preparing for a TypeScript interview? We analyze the most popular questions that are asked in interviews: from basic concepts to advanced techniques. Generic, Type Guards, Utility Types, Mapped Types and much more with code examples and explanations.

К

Kodik

Author

calendar_today
schedule10 min read

You know that moment when the recruiter writes "basic knowledge of TypeScript is required", and then at the interview they ask about covariance and contravariance? Yeah, yeah, we've all been there. It's time to figure out what they actually ask at TypeScript interviews and how to answer so that you look like a person who has read not only the documentation, but also the compiler's source code (spoiler: not necessarily).

Let's take a look at the most popular questions that people like to ask at job interviews. But not just "what is an interface", but with real situations and explanations of why it even matters to anyone.

1. "What is the difference between interface and type?"

Difficulty level: It seems simple until you start answering

It's like asking "what's the difference between pizza and pasta" – both are made of dough, both are Italian, but the serving is different.

A short answer for the impatient:

  • interface – for objects, expandable, can be declared multiple times (declaration merging)

  • type – for everything else, including union, intersection, primitives

Detailed response for impressions:

// Interface loves inheritance and addition
interface User {
  name: string;
}

interface User {
  age: number; // Merge with the previous one!
}

// Type is an alias, cannot be overridden
type Product = {
  id: number;
}

// type Product = { ... } // ❌ Error!

// But type can do cool stuff:
type Status = 'pending' | 'success' | 'error';
type Response<T> = { data: T } | { error: string };

What to say at the interview: "In practice, I use interface to describe data structures that can be expanded (for example, API types), and type for union types, utilities, and more complex structures. Interface is better for objects due to declaration merging."

🔥 100,000+ students already with us

Tired of reading theory?
Time to code!

Kodik — an app where you learn to code through practice. AI mentor, interactive lessons, real projects.

🤖 AI 24/7
🎓 Certificates
💰 Free
🚀 Start learning
Joined today

2. "What are Generic and why are they needed?"

Difficulty level: Sounds scary, but it's actually logical

Generics are like a template in Word. Once you've written it, you can substitute any data.

// Without Generic - pain and suffering
function getFirstElementString(arr: string[]): string {
  return arr[0];
}

function getFirstElementNumber(arr: number[]): number {
  return arr[0];
}

// With Generic - once and for all
function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

const firstString = getFirstElement(['a', 'b']); // string
const firstNumber = getFirstElement([1, 2, 3]); // number

Advanced level (to surprise):

// Generic with restrictions
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Alexey', age: 25 };
getProperty(user, 'name'); // ✅ OK
getProperty(user, 'salary'); // ❌ Compilation error!

3. "Explain unknown vs any vs never"

Difficulty level: Philosophical question in the world of types

Imagine: any is "I don't care", unknown is "I don't know, but I'll check", never is "this can't be at all".

// any - anarchy, do whatever you want
let chaos: any = 5;
chaos.doWhatever(); // Compiler: "Okay, your problems"
// unknown - safe uncertainty
let mystery: unknown = 5;
// mystery.doSomething(); // ❌ Error!

// First, let's check
if (typeof mystery === 'number') {
  mystery.toFixed(2); // ✅ Now OK
}

// never - for unreachable code
function throwError(message: string): never {
  throw new Error(message);
  // The code will never reach here
}

type Shape = Circle | Square;
function getArea(shape: Shape) {
  switch(shape.kind) {
    case 'circle': return Math.PI * shape.radius ** 2;
    case 'square': return shape.size ** 2;
    default:
      const _exhaustive: never = shape; // Completeness check
      return _exhaustive;
  }
}

Golden rule: Use unknown instead of any when you don't know the type. Your colleagues will thank you.

4. "What are Utility Types and which ones do you use?"

Difficulty level: Shows whether you have worked with real projects

Utility Types are built-in TypeScript helpers. It's like a Swiss knife for types.

interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

// Partial - all fields are optional
type UserUpdate = Partial<User>;
// { id?: number; name?: string; ... }

// Pick - select the required fields
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string }

// Omit - exclude fields
type UserPublic = Omit<User, 'password'>;
// { id: number; name: string; email: string }

// Record - create a structure
type UserRoles = Record<'admin' | 'user' | 'guest', string[]>;
// { admin: string[]; user: string[]; guest: string[] }

// ReturnType - type of the return value
function getUser() {
  return { id: 1, name: 'Alex' };
}
type User = ReturnType<typeof getUser>;

Life hack for the social security: Mention Readonly, Required, NonNullable – you will show that you know not only popular ones.

5. "What are Type Guards and how to create them?"

Difficulty level: Medium, but very practical

Type Guards is a way to convince TypeScript that you know what type of data is in front of you.

// Simple type guard
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

// More complex
interface Cat {
  meow: () => void;
}

interface Dog {
  bark: () => void;
}

function isCat(animal: Cat | Dog): animal is Cat {
  return (animal as Cat).meow !== undefined;
}

function makeSound(animal: Cat | Dog) {
  if (isCat(animal)) {
    animal.meow(); // TypeScript knows it's Cat
  } else {
    animal.bark(); // And here - Dog
  }
}

// Using the 'in' operator
type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    animal.swim();
  } else {
    animal.fly();
  }
}

6. "Tell me about keyof and typeof"

Difficulty level: This is where the middles are separated from the junks

interface User {
  id: number;
  name: string;
  email: string;
}

// keyof - get union of all keys
type UserKeys = keyof User; // 'id' | 'name' | 'email'

// typeof - get the type from the value
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3
};

type Config = typeof config;
// { apiUrl: string; timeout: number; retries: number }

// Combo: keyof typeof
const Colors = {
  red: '#ff0000',
  blue: '#0000ff',
  green: '#00ff00'
} as const;

type ColorKey = keyof typeof Colors; // 'red' | 'blue' | 'green'

// Practical application
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

7. "What are Mapped Types?"

Difficulty level: Senior territory

Mapped Types is when you turn one type into another, like an alchemist.

type User = {
  name: string;
  age: number;
  email: string;
}

// Make all fields readonly
type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};

// We make all fields optional
type PartialUser = {
  [K in keyof User]?: User[K];
};

// We make all fields nullable
type NullableUser = {
  [K in keyof User]: User[K] | null;
};

// Creating getters
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<User>;
// {
//   getName: () => string;
//   getAge: () => number;
//   getEmail: () => string;
// }

8. "What is the difference between enum and union types?"

Difficulty level: A simple question with a catch

// Enum - creates a real JavaScript object
enum Status {
  Pending = 'PENDING',
  Success = 'SUCCESS',
  Error = 'ERROR'
}

console.log(Status.Pending); // 'PENDING' - exists in runtime!

// Union - only at the type level
type StatusUnion = 'PENDING' | 'SUCCESS' | 'ERROR';

// In runtime, it's just a string
const status: StatusUnion = 'PENDING';

// Const enum - compiles into values
const enum Direction {
  Up,
  Down,
  Left,
  Right
}

const dir = Direction.Up; // Turn into 0

What to say: "I prefer union types for simple cases, as they do not add runtime code. I use Enum when I need feedback (reverse mapping) or when I need values in runtime."

9. "What are Conditional Types?"

Difficulty level: If you understood this, you are no longer a junior

Conditional Types is a ternary operator for types.

// Basic syntax
type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

// Case study
type Flatten<T> = T extends Array<infer U> ? U : T;

type StrArray = Flatten<string[]>; // string
type Num = Flatten<number>; // number

// Even cooler
type NonNullable<T> = T extends null | undefined ? never : T;

type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string

// Distributed Conditional Types
type ToArray<T> = T extends any ? T[] : never;
type StrOrNumArray = ToArray<string | number>;
// string[] | number[]

10. "Tell me about infer keyword"

Difficulty level: This is already magic

infer allows you to "pull" a type from another type.

// Get the type of the function return value
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: 'Alex' };
}

type User = ReturnType<typeof getUser>; // { id: number; name: string }

// Get the type of the array element
type ArrayElement<T> = T extends (infer U)[] ? U : never;

type NumArray = number[];
type Num = ArrayElement<NumArray>; // number

// Get the type of function parameters
type Parameters<T> = T extends (...args: infer P) => any ? P : never;

function createUser(name: string, age: number) {}

type CreateUserParams = Parameters<typeof createUser>; // [string, number]

// Promises
type Awaited<T> = T extends Promise<infer U> ? U : T;

type AsyncResult = Awaited<Promise<string>>; // string

💡 How do you remember all this and start applying it?

Honestly? Reading articles is cool, but without practice, it will all be gone in a week. You really need to write code and face problems.

That's why we created Kodik - an application where theory immediately turns into practice. No endless lectures, just code and challenges.

Plus, we have Telegram channel with a community of 2000+ developers, where useful posts, task reviews, memes (where without them) and discussions are published every day. It's like Stack Overflow, but in a human way and in Russian.

Bonus questions that can also be asked:

11. "What is Declaration Merging?"

interface Box {
  height: number;
}

interface Box {
  width: number;
}

// TypeScript will combine both into:
// interface Box {
//   height: number;
//   width: number;
// }

12. "Why do I need as const?"

// Without as const
const colors = ['red', 'blue']; // string[]

// С as const
const colorsConst = ['red', 'blue'] as const; // readonly ['red', 'blue']

// Practical application
const routes = {
  home: '/',
  about: '/about',
  contact: '/contact'
} as const;

type Route = typeof routes[keyof typeof routes]; 
// '/' | '/about' | '/contact'

13. "What are Template Literal Types?"

type Direction = 'up' | 'down' | 'left' | 'right';
type Move = `move${Capitalize<Direction>}`; 
// 'moveUp' | 'moveDown' | 'moveLeft' | 'moveRight'

type EventName = 'click' | 'focus' | 'blur';
type Handler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'

Conclusion: How to prepare for the interview

A week before:

  1. Go through the official TypeScript documentation

  2. Solve the tasks on Type Challenges (github.com/type-challenges/type-challenges)

  3. Practice explaining concepts aloud

The day before:

  1. Repeat the main concepts from this article

  2. Prepare examples from your projects

  3. Get enough sleep (seriously, it's more important than cramming)

At the interview:

  • Don't be afraid to say "I don't know, but I can look it up"

  • It is better to explain the concept in your own words than to quote the documentation

  • Ask clarifying questions – it shows that you are thinking

Key points: TypeScript is a tool, not an end in itself. Understanding that Why typing is needed, it is more important than knowing all Utility Types by heart.

P.S. If your head is spinning after reading this, that's okay. TypeScript is not something you can learn overnight. Go back to this article, try the examples, make mistakes and learn. That's how it works.

Good luck with the interviews! May the compiler be with you ✨

🎯Stop procrastinating

Liked the article?
Time to practice!

In Kodik, you don't just read — you write code immediately. Theory + practice = real skills.

Instant practice
🧠AI explains code
🏆Certificate

No registration • No card