TypeScriptTypeScript45 min read

TypeScript Interview Questions: 50 Essential Questions for Developers

Comprehensive collection of 50 essential TypeScript interview questions covering types, interfaces, generics, advanced types, and TypeScript best practices. Free TypeScript interview questions with answers. TypeScript interview prep guide.

David Lee
December 16, 2025
0.0k0

This comprehensive guide covers 50 essential TypeScript interview questions that every TypeScript developer should know. These questions cover fundamental concepts, types, interfaces, generics, advanced types, and TypeScript best practices commonly asked in technical interviews.

Core TypeScript Concepts

Understanding TypeScript's core concepts is essential. These questions test your knowledge of types, type inference, type annotations, and how TypeScript extends JavaScript.

Types & Interfaces

TypeScript's type system is powerful. Master these questions to demonstrate your understanding of basic types, interfaces, type aliases, and when to use each.

Advanced Types

Advanced TypeScript features include generics, utility types, conditional types, and mapped types. These questions test your ability to work with complex type scenarios.

Classes & OOP

TypeScript enhances JavaScript classes with access modifiers, abstract classes, and interfaces. These questions cover object-oriented programming in TypeScript.

Best Practices & Modern TypeScript

Production-ready TypeScript requires understanding best practices, module systems, decorators, and modern TypeScript features. These questions cover real-world TypeScript development.

#TypeScript#TS#Interview#Types#Interfaces#Generics#TypeScript Interview#TS Interview#TypeScript Tutorial

Common Questions & Answers

Q1

What is TypeScript and what are its main features?

A

TypeScript is superset of JavaScript that adds static type checking. Main features: static typing, type inference, interfaces, classes, generics, enums, optional chaining, nullish coalescing. Compiles to JavaScript. Catches errors at compile-time, improves code quality and maintainability.

Q2

What is the difference between TypeScript and JavaScript?

A

TypeScript adds static typing to JavaScript. TypeScript has types, interfaces, generics, access modifiers. JavaScript is dynamically typed. TypeScript compiles to JavaScript. TypeScript catches errors at compile-time, JavaScript at runtime. TypeScript is optional typing, can gradually adopt.

typescript
// JavaScript
function add(a, b) {
  return a + b;
}

// TypeScript
function add(a: number, b: number): number {
  return a + b;
}
Q3

What are the basic types in TypeScript?

A

Basic types: number, string, boolean, null, undefined, void, any, unknown, never, object, array, tuple, enum. number for numbers, string for text, boolean for true/false, any for any type, unknown for type-safe any, never for unreachable code.

typescript
let num: number = 42;
let str: string = "hello";
let bool: boolean = true;
let arr: number[] = [1, 2, 3];
let tuple: [string, number] = ["hello", 42];
let anything: any = "can be anything";
let unknown: unknown = "type-safe any";
Q4

What is the difference between interface and type?

A

Interface: can be extended, merged (declaration merging), better for object shapes. Type: can represent unions, intersections, primitives, more flexible. Use interface for object shapes, type for unions/intersections. Both can be used similarly for objects.

typescript
// Interface
interface User {
  name: string;
  age: number;
}
interface Admin extends User {
  role: string;
}

// Type
type Status = "active" | "inactive";
type UserType = {
  name: string;
  age: number;
};
Q5

What is type inference?

A

Type inference automatically determines types without explicit annotations. TypeScript infers types from values, function return types, context. Use explicit types when inference is unclear or for documentation. let/const inference differs: const is literal, let is wider type.

typescript
// Type inference
let x = 42; // inferred as number
const y = "hello"; // inferred as "hello" (literal)
let z = [1, 2, 3]; // inferred as number[]

// Explicit types
let a: number = 42;
const b: string = "hello";
Q6

What are generics?

A

Generics create reusable components that work with multiple types. Syntax: <T>. Placeholder for type, specified when used. Enables type-safe code without losing flexibility. Common in functions, interfaces, classes. Example: Array<T>, Promise<T>, Map<K, V>.

typescript
function identity<T>(arg: T): T {
  return arg;
}

const num = identity<number>(42);
const str = identity<string>("hello");

interface Box<T> {
  value: T;
}

const box: Box<number> = { value: 42 };
Q7

What is the difference between any and unknown?

A

any disables type checking, allows any operation, not type-safe. unknown is type-safe top type, requires type checking before use. Use any sparingly (legacy code), unknown for values of unknown type. unknown forces type guards, any does not.

typescript
let anyValue: any = "hello";
anyValue.foo(); // No error (unsafe)

let unknownValue: unknown = "hello";
unknownValue.foo(); // Error
if (typeof unknownValue === "string") {
  unknownValue.toUpperCase(); // OK after type guard
}
Q8

What is the difference between void and never?

A

void means function returns nothing (undefined). never means function never returns (throws error, infinite loop). void for functions that don't return value. never for functions that never complete normally, exhaustive checks in switch statements.

typescript
function log(message: string): void {
  console.log(message);
  // Returns undefined
}

function throwError(message: string): never {
  throw new Error(message);
  // Never returns
}

function infiniteLoop(): never {
  while (true) {
    // Never returns
  }
}
Q9

What are union and intersection types?

A

Union type (|) represents value that can be one of several types. Intersection type (&) combines multiple types into one. Union: "string | number" means string OR number. Intersection: "A & B" means A AND B (has properties of both).

typescript
// Union type
type Status = "active" | "inactive" | "pending";
let status: Status = "active";

function process(value: string | number) {
  if (typeof value === "string") {
    value.toUpperCase();
  }
}

// Intersection type
type A = { a: number };
type B = { b: string };
type C = A & B; // { a: number; b: string }
Q10

What are optional properties?

A

Optional properties can be undefined. Mark with ? after property name. Allows objects to omit properties. Access with optional chaining (?.) or check for undefined. Useful for flexible object shapes, function parameters.

typescript
interface User {
  name: string;
  age?: number; // Optional
  email?: string;
}

const user1: User = { name: "John" }; // age and email optional
const user2: User = { name: "Jane", age: 30 };

function greet(user: User) {
  console.log(user.name);
  if (user.age) {
    console.log(user.age);
  }
  console.log(user.age?.toString()); // Optional chaining
Q11

What is readonly?

A

readonly makes properties immutable after initialization. Can be set in constructor or initializer, cannot be reassigned. Use for constants, immutable data structures. readonly arrays prevent mutation. Different from const (for variables).

typescript
interface Point {
  readonly x: number;
  readonly y: number;
}

const point: Point = { x: 10, y: 20 };
point.x = 30; // Error

class Person {
  readonly name: string;
  constructor(name: string) {
    this.name = name; // OK in constructor
  }
}

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

What are access modifiers?

A

Access modifiers control property/method visibility: public (default, accessible anywhere), private (only within class), protected (class and subclasses), readonly (immutable). TypeScript-only (removed in JavaScript), helps with encapsulation.

typescript
class BankAccount {
  public balance: number; // Accessible anywhere
  private accountNumber: string; // Only in this class
  protected owner: string; // Class and subclasses
  
  constructor(balance: number, accountNumber: string) {
    this.balance = balance;
    this.accountNumber = accountNumber;
  }
  
  private validate(): boolean {
    return this.balance > 0;
  }
}
Q13

What are utility types?

A

Utility types transform existing types. Common: Partial<T> (all optional), Required<T> (all required), Readonly<T> (all readonly), Pick<T, K> (select properties), Omit<T, K> (exclude properties), Record<K, V> (object type). Built-in type transformations.

typescript
interface User {
  name: string;
  age: number;
  email: string;
}

type PartialUser = Partial<User>; // All optional
type RequiredUser = Required<User>; // All required
type NameOnly = Pick<User, "name">; // { name: string }
type WithoutEmail = Omit<User, "email">; // { name: string; age: number }
type UserRecord = Record<string, User>; // { [key: string]: User }
Q14

What is type assertion?

A

Type assertion tells TypeScript type of value when you know more than compiler. Syntax: <Type>value or value as Type. Does not change runtime value, only type checking. Use when TypeScript cannot infer correct type. Different from type casting (runtime conversion).

typescript
let value: unknown = "hello";

// Type assertion
let str1 = value as string;
let str2 = <string>value;

// Assertion with angle bracket (not in JSX)
let num = <number>someValue;

// Assertion with 'as' (preferred in JSX)
let num2 = someValue as number;
Q15

What are type guards?

A

Type guards narrow types within conditional blocks. typeof, instanceof, in operator, custom type predicates. TypeScript uses guards to narrow union types. Enables type-safe code with unions. Custom guards use type predicate syntax: arg is Type.

typescript
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function process(value: string | number) {
  if (isString(value)) {
    value.toUpperCase(); // TypeScript knows it's string
  } else {
    value.toFixed(2); // TypeScript knows it's number
  }
}

class Dog {
  bark() {}
}
function isDog(animal: any): animal is Dog {
  return animal instanceof Dog;
}
Q16

What are enums?

A

Enums define set of named constants. Numeric enums (default, auto-increment), string enums (explicit values), const enums (inlined). Access with dot notation. Compiles to JavaScript object. Use for fixed set of related constants.

typescript
// Numeric enum
enum Status {
  Pending,    // 0
  Active,     // 1
  Inactive    // 2
}

// String enum
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}

// Const enum (inlined)
const enum Size {
  Small,
  Medium,
  Large
}
Q17

What are tuples?

A

Tuples are arrays with fixed length and known types at each position. Syntax: [Type1, Type2, ...]. Different from arrays (variable length, same type). Use for fixed-length sequences with different types. Example: coordinates [number, number], key-value [string, number].

typescript
// Tuple
let point: [number, number] = [10, 20];
let user: [string, number, boolean] = ["John", 30, true];

// Named tuple (TypeScript 4.0+)
type Point = [x: number, y: number];
let p: Point = [10, 20];

// Optional tuple elements
type Optional = [string, number?];
let opt: Optional = ["hello"];
let opt2: Optional = ["hello", 42];
Q18

What is function overloading?

A

Function overloading defines multiple function signatures for same function. TypeScript chooses correct signature based on arguments. Implementation signature must be compatible with all overloads. Enables type-safe functions with different parameter types.

typescript
// Function overloads
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {
  return a + b;
}

const num = add(1, 2); // number
const str = add("hello", "world"); // string

// Method overloading
class Calculator {
  add(a: number, b: number): number;
  add(a: string, b: string): string;
  add(a: any, b: any): any {
    return a + b;
  }
}
Q19

What are abstract classes?

A

Abstract classes cannot be instantiated directly, must be extended. Can have abstract methods (no implementation, must be implemented in subclass) and concrete methods. Use for base classes with shared behavior. Different from interfaces (no implementation).

typescript
abstract class Animal {
  abstract makeSound(): void; // Must be implemented
  
  move(): void {
    console.log("Moving...");
  }
}

class Dog extends Animal {
  makeSound(): void {
    console.log("Woof!");
  }
}

// const animal = new Animal(); // Error
const dog = new Dog(); // OK
Q20

What are decorators?

A

Decorators are special functions that modify classes, methods, properties, parameters. Syntax: @decorator. Experimental feature, requires enableDecorators. Used in frameworks (Angular, NestJS). Types: class, method, property, parameter decorators. Enable with experimentalDecorators.

typescript
// Class decorator
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
}

// Method decorator
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log("Called:", propertyKey);
    return original.apply(this, args);
  };
}
Q21

What is the difference between type and interface for function types?

A

Both can define function types. Interface: call signature syntax. Type: function type syntax. Interface can be extended, merged. Type more flexible for complex signatures. Use interface for object shapes, type for function types or unions.

typescript
// Interface
interface MathOperation {
  (x: number, y: number): number;
}

// Type
type MathOp = (x: number, y: number) => number;

const add: MathOperation = (x, y) => x + y;
const subtract: MathOp = (x, y) => x - y;
Q22

What are mapped types?

A

Mapped types create new types by transforming properties of existing type. Syntax: { [K in keyof T]: T[K] }. Iterates over keys, transforms values. Used in utility types (Partial, Readonly, Pick). Enables type transformations programmatically.

typescript
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Optional<T> = {
  [P in keyof T]?: T[P];
};

type Stringify<T> = {
  [P in keyof T]: string;
};

interface User {
  name: string;
  age: number;
}

type ReadonlyUser = Readonly<User>; // { readonly name: string; readonly age: number; }
Q23

What are conditional types?

A

Conditional types select types based on condition. Syntax: T extends U ? X : Y. If T extends U, result is X, else Y. Used for type transformations, utility types. Can be chained, used with infer keyword for pattern matching.

typescript
type NonNullable<T> = T extends null | undefined ? never : T;

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

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

type Example1 = NonNullable<string | null>; // string
type Example2 = ReturnType<() => number>; // number
type Example3 = Flatten<number[]>; // number
Q24

What is the keyof operator?

A

keyof operator gets union of keys from type. Returns union of string literal types. Used with mapped types, type constraints. Enables type-safe property access. Example: keyof { a: 1, b: 2 } is "a" | "b".

typescript
interface User {
  name: string;
  age: number;
  email: string;
}

type UserKeys = keyof User; // "name" | "age" | "email"

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

const user = { name: "John", age: 30, email: "john@example.com" };
const name = getProperty(user, "name"); // Type-safe
Q25

What is the typeof operator?

A

typeof operator gets type of value. Used in type contexts (not runtime). Returns type of variable, property, function. Useful for extracting types from values. Different from JavaScript typeof (runtime type checking).

typescript
const user = {
  name: "John",
  age: 30
};

type UserType = typeof user; // { name: string; age: number; }

function createUser(): typeof user {
  return { name: "Jane", age: 25 };
}

// Extract return type
type ReturnType = typeof Math.max; // (values: number[]) => number
Q26

What are index signatures?

A

Index signatures define structure for objects with dynamic keys. Syntax: [key: string]: Type. Allows accessing properties with string keys. Use when object structure is dynamic. Can combine with known properties. String and number index signatures.

typescript
interface Dictionary {
  [key: string]: number;
}

const dict: Dictionary = {
  "one": 1,
  "two": 2,
  "three": 3
};

interface Mixed {
  name: string; // Known property
  [key: string]: string | number; // Index signature
}

const mixed: Mixed = {
  name: "John",
  age: 30, // OK
  city: "NYC" // OK
};
Q27

What are rest parameters and spread operator in TypeScript?

A

Rest parameters collect remaining arguments into array. Type: ...args: Type[]. Spread operator expands array/object. TypeScript infers types. Rest in function parameters, spread in function calls/arrays/objects. Type-safe array/object manipulation.

typescript
// Rest parameters
function sum(...numbers: number[]): number {
  return numbers.reduce((a, b) => a + b, 0);
}

sum(1, 2, 3, 4); // 10

// Spread operator
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
Q28

What are default parameters?

A

Default parameters provide fallback values when argument not provided. Syntax: param: Type = defaultValue. TypeScript infers type from default. Optional parameters (param?: Type) can be undefined, default parameters have value. Use defaults for convenience.

typescript
function greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}!`;
}

greet("John"); // "Hello, John!"
greet("Jane", "Hi"); // "Hi, Jane!"

function createUser(name: string, age: number = 18, active: boolean = true) {
  return { name, age, active };
}
Q29

What are namespaces?

A

Namespaces organize code into logical groups. Syntax: namespace Name { }. Can be split across files. Access with dot notation. Legacy feature, prefer ES6 modules. Used in older TypeScript code, some libraries. Can be nested, exported.

typescript
namespace MathUtils {
  export function add(a: number, b: number): number {
    return a + b;
  }
  
  export function multiply(a: number, b: number): number {
    return a * b;
  }
}

const result = MathUtils.add(1, 2);

// Nested namespace
namespace Outer {
  export namespace Inner {
    export function doSomething() {}
  }
}
Q30

What are module augmentation?

A

Module augmentation extends existing module declarations. Syntax: declare module "module-name" { }. Adds types to existing modules. Useful for extending third-party libraries, adding types to JavaScript modules. Can augment interfaces, add new exports.

typescript
// Augment existing module
declare module "express" {
  interface Request {
    user?: User;
  }
}

// Now Request has user property
import { Request } from "express";
function handler(req: Request) {
  req.user; // TypeScript knows about user property
}
Q31

What are declaration files (.d.ts)?

A

Declaration files provide type information for JavaScript code. Extension: .d.ts. Contains only type information, no implementation. Used for: type definitions for JS libraries, ambient declarations. Can be in same file or separate. @types packages provide definitions.

typescript
// types.d.ts
declare module "my-library" {
  export function doSomething(): void;
  export const value: number;
}

// Usage
import { doSomething, value } from "my-library";
doSomething(); // TypeScript knows the type
Q32

What is the difference between const and readonly?

A

const is for variables, prevents reassignment. readonly is for properties, prevents modification after initialization. const: variable-level immutability. readonly: property-level immutability. const for values, readonly for object properties.

typescript
// const - variable
const x = 10;
x = 20; // Error

// readonly - property
interface Point {
  readonly x: number;
  readonly y: number;
}

const point: Point = { x: 10, y: 20 };
point.x = 30; // Error

// const with object
const obj = { a: 1 };
obj.a = 2; // OK (object is mutable)
obj = {}; // Error (variable is const)
Q33

What are template literal types?

A

Template literal types create string literal types from template strings. Syntax: `text${Type}`. Combines string literals with types. Used for type-safe string manipulation, API endpoints, CSS values. TypeScript 4.1+ feature.

typescript
type EventName<T extends string> = `on${Capitalize<T>}`;

type ClickEvent = EventName<"click">; // "onClick"
type ChangeEvent = EventName<"change">; // "onChange"

type ApiEndpoint = `/api/${string}`;
const endpoint: ApiEndpoint = "/api/users"; // OK
const invalid: ApiEndpoint = "/users"; // Error

type CSSValue = `${number}px`;
const width: CSSValue = "10px"; // OK
Q34

What are branded types?

A

Branded types add compile-time brand to prevent mixing similar types. Syntax: type Branded = Base & { __brand: "Brand" }. Prevents accidental mixing of types with same structure. Useful for IDs, measurements, currencies. Runtime no-op, compile-time safety.

typescript
type UserId = string & { __brand: "UserId" };
type ProductId = string & { __brand: "ProductId" };

function getUser(id: UserId) {
  // ...
}

const userId = "123" as UserId;
const productId = "456" as ProductId;

getUser(userId); // OK
getUser(productId); // Error
Q35

What is the difference between extends and implements?

A

extends creates inheritance relationship (class extends class, interface extends interface). implements enforces class implements interface. extends: "is-a" relationship, inherits implementation. implements: "has" relationship, enforces contract, no inheritance.

typescript
interface Flyable {
  fly(): void;
}

class Animal {
  move() {}
}

// extends - inheritance
class Bird extends Animal {
  // Inherits move()
}

// implements - contract
class Airplane implements Flyable {
  fly(): void {
    console.log("Flying");
  }
}

// Can combine
class FlyingBird extends Animal implements Flyable {
  fly(): void {
    console.log("Flying");
  }
}
Q36

What are discriminated unions?

A

Discriminated unions use common property (discriminant) to distinguish union members. Enables type narrowing, type-safe handling of union types. Pattern: each member has same property with different literal value. TypeScript narrows based on discriminant.

typescript
type Success = {
  status: "success";
  data: string;
};

type Error = {
  status: "error";
  message: string;
};

type Result = Success | Error;

function handle(result: Result) {
  if (result.status === "success") {
    console.log(result.data); // TypeScript knows it's Success
  } else {
    console.log(result.message); // TypeScript knows it's Error
  }
}
Q37

What are const assertions?

A

Const assertions make values readonly and infer literal types. Syntax: as const. Prevents widening, makes arrays/tuples readonly, infers literal types. Useful for configuration objects, enums, preventing mutations. TypeScript 3.4+ feature.

typescript
// Without const assertion
let arr = [1, 2, 3]; // number[]

// With const assertion
let arr2 = [1, 2, 3] as const; // readonly [1, 2, 3]

const config = {
  api: "https://api.example.com",
  timeout: 5000
} as const;

// config.api is "https://api.example.com" (literal)
// config is readonly
Q38

What are satisfies operator?

A

satisfies operator (TypeScript 4.9+) ensures value matches type without widening. Preserves literal types while checking compatibility. Syntax: value satisfies Type. Better than type annotation (preserves types) and type assertion (type-safe).

typescript
type Colors = "red" | "green" | "blue";

// With satisfies - preserves literal types
const colors = {
  primary: "red",
  secondary: "green"
} satisfies Record<string, Colors>;

// colors.primary is "red" (literal), not string

// Without satisfies - widens to string
const colors2: Record<string, Colors> = {
  primary: "red",
  secondary: "green"
};
// colors2.primary is string
Q39

What are async/await in TypeScript?

A

Async/await works with promises in TypeScript. async function returns Promise<T>. await pauses execution until promise resolves. TypeScript infers Promise types. Errors caught with try/catch. Type-safe asynchronous code.

typescript
async function fetchUser(id: number): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  const user: User = await response.json();
  return user;
}

async function process() {
  try {
    const user = await fetchUser(1);
    console.log(user.name);
  } catch (error) {
    console.error(error);
  }
}
Q40

What are type predicates?

A

Type predicates are functions that return type assertion. Syntax: arg is Type. Used in type guards. TypeScript narrows type in conditional blocks. Enables custom type narrowing. Must return boolean, assertion in return type.

typescript
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function isNumber(value: unknown): value is number {
  return typeof value === "number";
}

function process(value: unknown) {
  if (isString(value)) {
    value.toUpperCase(); // TypeScript knows it's string
  } else if (isNumber(value)) {
    value.toFixed(2); // TypeScript knows it's number
  }
}
Q41

What are this types?

A

this types represent type of this context. Used in methods, classes. Enables method chaining, fluent interfaces. TypeScript tracks this type in different contexts. Useful for builder patterns, method chaining.

typescript
class Calculator {
  value: number = 0;
  
  add(n: number): this {
    this.value += n;
    return this;
  }
  
  multiply(n: number): this {
    this.value *= n;
    return this;
  }
}

const calc = new Calculator();
calc.add(5).multiply(2).add(10); // Method chaining

interface Builder {
  setValue(value: number): this;
  build(): Product;
}
Q42

What are parameter properties?

A

Parameter properties declare and initialize class members in constructor parameters. Syntax: constructor(public/private/protected/readonly name: Type). Shorthand for declaring and assigning. Reduces boilerplate. Access modifier required.

typescript
// Without parameter properties
class User {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

// With parameter properties
class User2 {
  constructor(public name: string, private age: number) {
    // name and age automatically declared and assigned
  }
}

const user = new User2("John", 30);
user.name; // OK
user.age; // Error (private)
Q43

What are getters and setters?

A

Getters and setters control property access. get property() { } for reading, set property(value) { } for writing. Can add logic, validation, computed properties. TypeScript infers return types. Use for encapsulation, computed values.

typescript
class Temperature {
  private _celsius: number = 0;
  
  get celsius(): number {
    return this._celsius;
  }
  
  set celsius(value: number) {
    if (value < -273.15) {
      throw new Error("Temperature too low");
    }
    this._celsius = value;
  }
  
  get fahrenheit(): number {
    return this._celsius * 9/5 + 32;
  }
}

const temp = new Temperature();
temp.celsius = 25;
console.log(temp.fahrenheit); // 77
Q44

What are static members?

A

Static members belong to class, not instances. Access with ClassName.member, not instance.member. Can be properties, methods. Shared across all instances. Use for utility methods, constants, factory methods. Cannot access instance members.

typescript
class MathUtils {
  static PI = 3.14159;
  
  static add(a: number, b: number): number {
    return a + b;
  }
  
  static create(value: number): MathUtils {
    return new MathUtils(value);
  }
  
  constructor(private value: number) {}
}

console.log(MathUtils.PI);
const sum = MathUtils.add(1, 2);
const instance = MathUtils.create(10);
Q45

What are mixins?

A

Mixins combine multiple classes into one. TypeScript supports mixins through intersection types and helper functions. Enables multiple inheritance-like behavior. Use for reusable behavior, composition over inheritance. Pattern: apply mixins to class.

typescript
class Disposable {
  dispose() {
    console.log("Disposing");
  }
}

class Activatable {
  activate() {
    console.log("Activating");
  }
}

type Constructor = new (...args: any[]) => {};

function applyMixins(derivedCtor: Constructor, baseCtors: Constructor[]) {
  baseCtors.forEach(baseCtor => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
      derivedCtor.prototype[name] = baseCtor.prototype[name];
    });
  });
}

class SmartObject implements Disposable, Activatable {
  dispose: () => void;
  activate: () => void;
}

applyMixins(SmartObject, [Disposable, Activatable]);
Q46

What are ambient declarations?

A

Ambient declarations describe types for existing JavaScript code. Syntax: declare. No implementation, only types. Used for: global variables, module types, library types. declare var, declare function, declare class, declare module, declare namespace.

typescript
// Global variable
declare var GLOBAL_CONFIG: {
  apiUrl: string;
  timeout: number;
};

// Global function
declare function log(message: string): void;

// Module declaration
declare module "my-module" {
  export function doSomething(): void;
}

// Usage
console.log(GLOBAL_CONFIG.apiUrl);
log("Hello");
Q47

What are triple-slash directives?

A

Triple-slash directives are single-line comments with three slashes. Types: /// <reference path="..." /> (includes file), /// <reference types="..." /> (includes types), /// <amd-module /> (AMD module name). Legacy feature, prefer import/export.

typescript
/// <reference path="types.d.ts" />
/// <reference types="node" />
/// <amd-module name="MyModule" />

// Now types from types.d.ts and @types/node are available
Q48

What is the difference between interface merging and type intersection?

A

Interface merging combines multiple interface declarations with same name. Type intersection (&) combines types explicitly. Merging: automatic, multiple declarations merge. Intersection: explicit, combines types. Merging for extending interfaces, intersection for combining types.

typescript
// Interface merging
interface User {
  name: string;
}
interface User {
  age: number;
}
// User is { name: string; age: number; }

// Type intersection
type A = { a: number };
type B = { b: string };
type C = A & B; // { a: number; b: string; }
Q49

What are utility types: Partial, Required, Readonly, Pick, Omit?

A

Partial<T>: all properties optional. Required<T>: all properties required. Readonly<T>: all properties readonly. Pick<T, K>: select properties. Omit<T, K>: exclude properties. Built-in type transformations for common patterns.

typescript
interface User {
  name: string;
  age: number;
  email: string;
}

type PartialUser = Partial<User>; // All optional
type RequiredUser = Required<User>; // All required
type ReadonlyUser = Readonly<User>; // All readonly
type NameOnly = Pick<User, "name">; // { name: string }
type WithoutEmail = Omit<User, "email">; // { name: string; age: number }
Q50

What are best practices for TypeScript?

A

Best practices: use strict mode, avoid any (use unknown), prefer interfaces for objects, use type for unions/intersections, enable strictNullChecks, use readonly for immutability, prefer const assertions, use utility types, avoid type assertions when possible, write type definitions for libraries, use discriminated unions for type safety.

typescript
// Good practices
interface User {
  readonly id: string;
  name: string;
  age?: number;
}

function processUser(user: User): void {
  // Type-safe code
}

// Avoid any
function bad(value: any) {} // Bad
function good(value: unknown) {
  if (typeof value === "string") {
    value.toUpperCase(); // Good
  }
}

// Use const assertions
const config = {
  api: "https://api.example.com"
} as const;