Skip to content
tezvyn:
Menu

Define a User object shape: interface vs type alias?

Source: typescriptlang.orgEasyHow cards are made

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's really being asked

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.

The full answer

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.

The mistakes people make

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.

What usually comes next

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?

A 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.

Interview question

When defining a User object shape for an external API that third-party modules may need to augment, why is an interface conventionally preferred over a type alias?

  • a.Type aliases cannot describe object shapes with optional or readonly properties.
  • b.Interfaces are erased differently during compilation, leaving a smaller runtime footprint.
  • c.Interfaces support declaration merging, so multiple modules can safely contribute to the same User definition.Correct
  • d.The choice is purely stylistic, as both constructs handle extension identically.
Why?

Interfaces are preferred because they support declaration merging, which lets separate files or plugins augment the User shape without conflicting definitions. The runtime performance claim is a common misconception because both constructs are fully erased during compilation and have zero runtime cost.

Just read this? Test yourself on what you have been reading.

Read the original → typescriptlang.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on typescript — each one lists the topics its interview covers.

See open roles