TypeScript

Collections

Overrated?

Type, interface

Differences Between Type Aliases and Interfaces

Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

Extending an interface

interface Animal {
  name: string
}
interface Bear extends Animal {
  honey: boolean
}
const bear = getBear()
bear.name
bear.honey

Extending a type via intersections

type Animal = {
  name: string
}
type Bear = Animal & { honey: boolean }
const bear = getBear()
bear.name
bear.honey

Adding new fields to an existing interface

interface Window {
  title: string
}
interface Window {
  ts: TypeScriptAPI
}
const src = 'const a = "Hello World"'
window.ts.transpileModule(src, {})

A type cannot be changed after being created

type Window = { title: string }
type Window = { ts: TypeScriptAPI }
// Error: Duplicate identifier 'Window'.

Preferring Interfaces Over Intersections

Much of the time, a simple type alias to an object type acts very similarly to an interface.

interface Foo {
  prop: string
}

type Bar = { prop: string }

However, and as soon as you need to compose two or more types, you have the option of extending those types with an interface, or intersecting them in a type alias, and that's when the differences start to matter.

Interfaces create a single flat object type that detects property conflicts, which are usually important to resolve! Intersections on the other hand just recursively merge properties, and in some cases produce never. Interfaces also display consistently better, whereas type aliases to intersections can't be displayed in part of other intersections. Type relationships between interfaces are also cached, as opposed to intersection types as a whole. A final noteworthy difference is that when checking against a target intersection type, every constituent is checked before checking against the "effective"/"flattened" type.

For this reason, extending types with interfaces/extends is suggested over creating intersection types.

- type Foo = Bar & Baz & {
-     someProp: string;
- }
+ interface Foo extends Bar, Baz {
+     someProp: string;
+ }

Children
  1. 10 Advanced TypeScript Tips for Development
  2. 11 Awesome TypeScript Utility Types You Should Know
  3. 13 Typescript Utility - A Cheat Sheet for Developer
  4. Favour TypeScript Types Over Interfaces
  5. No More Confusion About TypeScript’s Type and Interface
  6. Record Type in TypeScript
  7. Stop using {} in Typescript
  8. Tools
  9. TypeScript Advanced Types for Next.js: Examples and Best Practices In 2023