TypeScript Best Practices

Chapter 2 · Practice 5 of 6

Mark data you do not mean to change as readonly

From Modeling data with types

Why it matters

readonly properties and readonly T[] (or ReadonlyArray<T>) stop accidental mutation at compile time. They are most useful on:

  • function parameters, so callers know you will not change their arrays,
  • configuration objects and constants,
  • state that a framework expects you to replace rather than mutate, such as React state.

readonly is a compile-time check only: it does not freeze the object at runtime. Use Object.freeze when you also need runtime protection.

Do

  • Accept readonly T[] in functions that only read an array
  • Use as const for constant configuration objects

Avoid

  • Sorting or pushing into an array you received as a parameter

Example

TypeScript
function total(prices: readonly number[]): number {
  // prices.sort() would be a type error here
  return prices.reduce((sum, p) => sum + p, 0);
}