Access Keys or Values in TypeScript

- 3 min read
A code snippet using typescript

Objects

Get the type of a value

const User = {
  name: 'Juan',
  age: 26,
  isDev: true,
  id: null,
};

type Data = typeof User;
type Name = Data['name']; // string
type Age = Data['age']; // number
type Dev = Data['isDev']; // boolean
type Id = Data['id']; // null

Get the value as type

const User = {
  name: 'Juan',
  age: 26,
  isDev: true,
  id: null,
} as const; // Note the use of -> as const

type Data = typeof User;
type Name = Data['name']; // Juan
type Age = Data['age']; // 26
type Dev = Data['isDev']; // true
type Id = Data['id']; // null
// For Id, null is the value and the type are the same thing

Convert object to union

const User = {
  name: 'Juan',
  age: 26,
  isDev: true,
  id: null,
} as const;

// union from keys
type KeysUnion = keyof typeof User;
// "name" | "age" | "isDev" | "id"

// union from values
type ValuesUnion = (typeof User)[keyof typeof User];
// true | "Juan" | 26 | null

// If you don't add 'as const', you will obtain the types of each value
const User = {
  name: 'Juan',
  age: 26,
  isDev: true,
  id: null,
}; // as const

type ValuesUnion = (typeof User)[keyof typeof User];
// string | number | boolean | null

Create union using utilities

const User = {
  name: 'Juan',
  age: 26,
  isDev: true,
  id: null,
} as const;

type DataUnion = (typeof User)[Exclude<keyof typeof User, 'age' | 'isDev'>];
// 'Juan' | null;
type DataUnion = (typeof User)[Extract<keyof typeof User, 'age' | 'isDev'>];
// true | 26;

// Optionally, you can use types to improve readability

type TUser = typeof User;
type KeysUnion = keyof TUser;

type DataUnion = TUser[Exclude<KeysUnion, 'age' | 'isDev'>];
// 'Juan' | null;
type DataUnion = TUser[Extract<KeysUnion, 'age' | 'isDev'>];
// true | 26;

Arrays

const animals = ['🐶', '🐱', '🦄'] as const;

type DogOrCat = (typeof animals)[0 | 1]; // "🐶" | "🐱"
type Animals = (typeof animals)[number]; // "🐶" | "🐱" | "🦄"

Discriminated unions

Discriminated unions are unions with common properties used to distinguish each member of the union.

Convert discriminated union

type Event =
  | {
      type: 'click';
      event: MouseEvent;
    }
  | {
      type: 'focus';
      event: FocusEvent;
    }
  | {
      type: 'keydown';
      event: KeyboardEvent;
    };

type ClickEvent = Event['type'];
// "click" | "focus" | "keydown"

type ClickEvent = Event['event'];
// MouseEvent | FocusEvent | KeyboardEvent

Convert union using utilities

type Event =
  | {
      type: 'click';
      event: MouseEvent;
    }
  | {
      type: 'focus';
      event: FocusEvent;
    }
  | {
      type: 'keydown';
      event: KeyboardEvent;
    };

// You can also use something like: { event: MouseEvent }

type ClickEvent = Extract<Event, { type: 'click' }>;
//  { type: 'click'; event: MouseEvent; }

type FocustAndKeyboardEvent = Exclude<Event, { type: 'click' }>;
//  { type: 'focus'; event: FocusEvent; } | { type: 'keydown'; event: KeyboardEvent; }

PS: These are my notes from the Total TypeScript course. If you want to delve deeper, I highly recommend the course, it is excellent.