Types and Interfaces Interview Questions
What is the difference between an interface and a type alias?
- Both can describe object shapes and both can be extended (
extendsvs&). - Only
typecan name unions, tuples, primitives, mapped and conditional types. - Only
interfacesupports declaration merging (two declarations with the same name merge), which is how libraries let you augment types. - Interfaces can give slightly faster type checking and clearer error messages for large object hierarchies.
Common team rule: interface for object contracts, type for everything else.
What is structural typing?
TypeScript compares types by their shape, not their name (also called duck typing). Any value with the required properties is accepted, even if it was never declared as that type. That is why a Point class parameter accepts a plain { x, y } object. To get nominal behaviour (e.g. UserId vs OrderId), use branded types.
Structural Typing
interface HasPrice { price: number }
const total = (items: HasPrice[]) => items.reduce((s, i) => s + i.price, 0);
const book = { title: "Clean Code", price: 500 };
const course = { name: "TS", price: 1999, hours: 20 };
console.log(total([book, course]));Output
2499
What is the excess property check?
When you assign an object literal directly to a typed target, TypeScript reports properties that the target does not have. It catches typos like { prise: 10 }. It does not apply when the object comes from a variable (structural typing allows extra properties there).
Fresh Literal vs Variable
type Product = { name: string; price: number };
const extra = { name: "Pen", price: 20, color: "blue" };
const a: Product = extra; // OK: not a fresh literal
const b: Product = { name: "Pen", price: 20, color: "blue" }; // errorCompiler output (tsc)
Line 5: error TS2353: Object literal may only specify known properties, and 'color' does not exist in type 'Product'.
What are union and intersection types?
A union A | B is a value that is either A or B: you can only use members common to both until you narrow. An intersection A & B has all members of both. Example: type Id = string | number; type AuditedUser = User & { createdAt: string }. Intersecting incompatible primitives gives never (string & number).
What are index signatures and what is the risk?
{ [key: string]: number } (or Record<string, number>) describes objects with arbitrary keys. The risk: by default, reading obj["missing"] is typed as number although it is undefined at runtime. Enable noUncheckedIndexedAccess or use a Map (whose get returns V | undefined).