Basic TypeScript Interview Questions
Question 1: What is TypeScript and how does it differ from JavaScript?
TypeScript is a superset of JavaScript that adds static typing, interfaces, and advanced features to improve code reliability and scalability. It compiles to plain JavaScript and catches type errors at compile time, unlike JavaScript’s dynamic typing which detects errors only at runtime.[1][2]
Question 2: What does it mean that TypeScript is a superset of JavaScript?
Every valid JavaScript code is also valid TypeScript code, allowing seamless migration of existing JavaScript projects to TypeScript with minimal changes.[1]
Question 3: What are the primitive types in TypeScript?
TypeScript primitive types include number, string, boolean, null, undefined, symbol, and bigint. These provide type safety for basic data values.[4][5]
Question 4: How do you declare variables with explicit types in TypeScript?
Use type annotations with a colon after the variable name. Here’s an example:
const productId: number = 123;
const productName: string = 'Laptop';
const isActive: boolean = true;
This catches type mismatches at compile time.[1][4]
Question 5: What is the difference between let, const, and var in TypeScript?
let allows reassignment within block scope, const prevents reassignment but allows mutation of objects/arrays, and var has function scope and can be hoisted. TypeScript recommends let and const for better safety.[1]
Question 6: What are TypeScript interfaces?
Interfaces define the shape of objects, ensuring consistent structure across your codebase. They help with type checking without affecting runtime code.
interface Product {
id: number;
name: string;
price: number;
}
const laptop: Product = { id: 1, name: 'MacBook', price: 999 };
[1][2]
Question 7: How do optional properties work in TypeScript interfaces?
Optional properties use the ? operator, making them non-required during object creation.
interface User {
name: string;
email?: string;
}
const user: User = { name: 'John' }; // Valid
[7]
Question 8: What is type inference in TypeScript?
TypeScript automatically determines variable types from assigned values, reducing boilerplate while maintaining type safety.
const count = 10; // TypeScript infers 'number'
const message = 'Hello'; // TypeScript infers 'string'
[2]
Question 9: What is the ‘any’ type and when should you avoid it?
The any type disables type checking, allowing any operation. Avoid it to maintain TypeScript’s type safety benefits.[2]
Question 10: How do you enable strict null checks in TypeScript?
Set "strictNullChecks": true in tsconfig.json or use the --strictNullChecks compiler flag to catch null/undefined errors at compile time.[3][5]
Intermediate TypeScript Interview Questions
Question 11: What are TypeScript union types?
Union types allow a variable to be one of several types, specified with the pipe (|) operator.
let id: string | number;
id = 'ABC123'; // Valid
id = 123; // Valid
[2]
Question 12: Explain TypeScript enums with an example.
Enums define a set of named constants, improving code readability and preventing magic values.
enum OrderStatus {
PENDING = 'pending',
SHIPPED = 'shipped',
DELIVERED = 'delivered'
}
const order: OrderStatus = OrderStatus.SHIPPED;
[1]
Question 13: What is type assertion in TypeScript?
Type assertion tells the compiler to treat a value as a specific type using as keyword. Use cautiously as it bypasses type checking.
const value = '123' as number; // Not recommended
const safeValue = (value as any) as number;
[2]
Question 14: How do function types work in TypeScript?
Functions can have typed parameters and return types for better safety.
function calculatePrice(price: number, taxRate: number): number {
return price * (1 + taxRate);
}
[4]
Question 15: What are TypeScript generics?
Generics create reusable components that work with multiple types while maintaining type safety.
function identity<T>(value: T): T {
return value;
}
const num = identity<number>(42);
const str = identity<string>('hello');
[4]
Question 16: Explain mapped types in TypeScript.
Mapped types transform existing types by applying changes to all properties. Common example is Partial<T>.
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User { name: string; age: number; }
type PartialUser = Partial<User>;
[2]
Question 17: What is the difference between interface and type alias?
Interfaces are open for extension using declaration merging, while type aliases create new types. Use interfaces for object shapes, types for unions/primitives.
Question 18: How does optional chaining work in TypeScript?
Optional chaining (?.) safely accesses nested properties, returning undefined instead of throwing errors.
interface User {
address?: { city?: string };
}
const user: User = {};
const city = user.address?.city; // undefined, no error
[3]
Question 19: What are index signatures in TypeScript?
Index signatures allow objects with dynamic keys while maintaining type safety.
interface StringDictionary {
[key: string]: string | number;
}
const dict: StringDictionary = {
name: 'John',
age: 30
};
Question 20: Explain TypeScript modules and exports.
TypeScript supports ES modules with import/export syntax for better code organization.
// product.ts
export interface Product {
id: number;
name: string;
}
// main.ts
import { Product } from './product';
[6]
Advanced TypeScript Interview Questions
Question 21: What is conditional typing in TypeScript?
Conditional types use ternary operators to select types based on conditions, enabling powerful type-level programming.
type NonNullable<T> = T extends null | undefined ? never : T;
type T1 = NonNullable<string | null>; // string
[6][7]
Question 22: How do you implement utility types like Pick and Omit?
Utility types extract or exclude properties from existing types.
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface User {
name: string;
age: number;
email: string;
}
type UserPreview = Pick<User, 'name' | 'age'>;
[2]
Question 23: Explain discriminated unions in TypeScript.
Discriminated unions use a common literal discriminant property for type narrowing.
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; sideLength: number };
function area(shape: Shape) {
if (shape.kind === 'circle') {
return Math.PI * shape.radius ** 2;
}
return shape.sideLength ** 2;
}
Question 24: What are template literal types?
Template literal types create string literal unions from patterns.
type Event = 'click' | 'hover' | 'focus';
type EventName = `on${Capitalize<Event>}`;
// "onClick" | "onHover" | "onFocus"
Question 25: How do you create readonly types in TypeScript?
Use readonly modifier to prevent property mutation.
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 10, y: 20 };
// point.x = 15; // Error!
Question 26: Explain TypeScript’s never type.
The never type represents values that never occur, useful for exhaustive checking or impossible states.
function exhaustiveCheck(value: never): never {
throw new Error(`Unhandled case: ${value}`);
}
[2]
Question 27: What are correlated records?
Correlated records ensure multiple properties have compatible types simultaneously.
type Correlated<K extends string, V> = {
[P in K]: V;
};
type Valid = Correlated<'id' | 'name', string | number>;
Question 28: How do you implement custom type guards?
Type guards narrow types within conditional blocks using user-defined functions.
function isString(value: unknown): value is string {
return typeof value === 'string';
}
if (isString(data)) {
// data is now typed as string
console.log(data.toUpperCase());
}
Question 29: Explain infer keyword usage.
The infer keyword extracts types from other types within conditional types.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Func = () => string;
type Returns = ReturnType<Func>; // string
[6]
Question 30: At Atlassian, how would you type a generic API response handler?
Create a generic wrapper type with proper error handling and data typing.
interface ApiResponse<T> {
data: T;
success: boolean;
error?: string;
}
function fetchProduct<T>(id: number): Promise<ApiResponse<T>> {
// Implementation
}
const response = await fetchProduct<{name: string}>(123);