Define a User object shape: interface vs type alias?
Tests structural typing and API contracts. Good answer: interface for API objects because it merges; type alias for unions. Forced: declaration merging needs interface; discriminated unions need type. Red flag: claiming performance differences.
WHAT THIS TESTS: Whether you understand TypeScript structural typing and can make idiomatic choices between interfaces and type aliases when modeling external API data. Interviewers want to see that you know interfaces are the conventional tool for object shapes and that you understand the specific edge cases that force one over the other.
A GOOD ANSWER COVERS: First, define User as an interface with readonly or optional fields matching the API schema, such as id, name, and email, because interfaces are the idiomatic and conventional choice for object shapes in TypeScript. Second, explain that interfaces support declaration merging, which is useful when multiple modules or third-party declarations contribute to the same type definition, and they often produce more helpful error messages during extension. Third, note that type aliases are better suited for unions, tuples, mapped types, or when you need to use the typeof operator to derive a type from an existing runtime value. Fourth, describe a forced choice scenario: you must use an interface if you need declaration merging across files or libraries, and you must use a type alias if you need a discriminated union, a tuple, or to alias a primitive type.
COMMON WRONG ANSWERS: Claiming that interfaces are faster than type aliases at runtime, since both constructs are completely erased during compilation and have zero runtime cost. Saying that type aliases cannot describe object shapes, when they absolutely can and often do for local or derived types. Recommending type aliases for all API objects without mentioning declaration merging or the conventional preference for interfaces in public library definitions. Giving a purely stylistic answer like always use one or the other without naming a single technical constraint that would force the decision.
LIKELY FOLLOW-UPS: How would you handle an API field that is sometimes missing, and would you model that with a union type or an optional property? How do you extend a User interface for an Admin role without duplicating fields across multiple type definitions? What happens if two third-party libraries both declare the same interface name in the global scope? Can you use a type alias to create a recursive type for a tree structure, and if so, how does that differ from using an interface?
ONE CONCRETE EXAMPLE: Imagine fetching a user from a REST endpoint. You write an interface named User with readonly id of type string, name of type string, and optional email of type string because it clearly documents an object contract and signals intent to other engineers. Later, a plugin in another file needs to augment User with a profile field, so it uses declaration merging by declaring another interface User with a profile property of type Profile. The TypeScript compiler automatically merges these declarations, but you cannot achieve this merge with a type alias. Conversely, if the API returns either a User or an Error payload, you must use a type alias named APIResponse that is a union of User and ApiError because interfaces cannot represent a union type directly.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.