Skip to content

TypeScript Objects

const activeGlobalFilters = typeToFilter[
    globalFilter
] as typeof filterOptions[keyof typeof filterOptions];

interface vs type

  • both are good, for consistency, stick with one
  • interfaces compile faster 🤷

What only interface can do

  • declaration merging
  • interfaces can be changed after being created
interface Point {
    x: number;
}
interface Point {
    y: number;
}
//becomes: interface Point { x: number; y: number; }

What only type can do

  • primitives
    • type Name = string
  • unions
    • type Id = string | number
  • tuples
    • type Data = [number, string]

Object that has at least these two properties

<T extends {first: string; last: string}>(obj: T)
/**
 * Make all properties in T optional
 */
type Partial<T> = {
    [P in keyof T]?: T[P];
};
/**
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};

Extend a type

interface LoadingWidgets {
    [widgetId?: number]: boolean;
}

interface IsLoading {
    widgets: LoadingWidgets;
    [key?: string]: boolean | LoadingWidgets;
}

Avoid optional properties

  • Explicitly model which combinations exist and which don't
interface Product {
    id: string;
    type: "digital" | "physical";
    weightInKg?: number;
    sizeInMb?: number;
}
interface Product {
    id: string;
    type: "digital" | "physical";
}

interface DigitalProduct extends Product {
    type: "digital";
    sizeInMb: number;
}

interface PhysicalProduct extends Product {
    type: "physical";
    weightInKg: number;
}

Record

Type objects

Restrict what the key and the value can be

type User = {
    firstName: string;
    lastName: string;
};
type Country = "uk" | "france" | "india";

const myData: Record<Country, User> = {
    uk: { firstName: "John", lastName: "Doe" },
    france: { firstName: "Sarah", lastName: "Doe" },
    india: { firstName: "Jane", lastName: "Smith" },
};

Record: object of string -> string

Record<string, string>;

object type vs UnknownObject

interface UnknownObject {
    [key: string]: unknown;
}

type UnknownObject = Record<string, unknown>;

object will match functions too!

thisIsValid.ts
const a: object = () => {};
(a: object) => a.something  // error

(a: UnknownObject) => a.something // unknown

Narrowing which props are accepted for subtypes

There is something


Last update: 2022-11-04