Skip to content
Nate
Stephens

Type Queries

Type queries allow us to obtain type information from values.

keyof

The keyof type query allows you to obtain types representing all property keys on a given interface.

This results in a union type.

type ObjectLiteralType = {
  first: 1;
  second: 2;
};

type Result = keyof ObjectLiteralType;
// Inferred Type: "first" | "second"

Narrow with an intersection operator

type DatePropertyNames = keyof Date;

Not all keys on Date are string's. One is a symbol.

We can separate out the different key types using the intersection operator (&).

  • "I only want to see the keys that are of type string", or...
  • "I only want to see the keys that are of type symbol"

With the intersection operator we're left with only the sub-part of the keyof Date keys that are also included by string or symbol.

type DatePropertyNames = keyof Date;

type DateStringPropertyNames = DatePropertyNames & string;
// type DateStringPropertyNames = "toString" | "toDateString" | ...

type DateSymbolPropertyNames = DatePropertyNames & symbol;
// type DateSymbolPropertyNames = typeof Symbol.toPrimitive

NOTE: this is similar to using the Extract TS utility

typeof

The typeof type query allows you to extract a type from a value.

async function main() {
  const apiResponse = await Promise.all([
    fetch('https://example.com'),
    Promise.resolve('Titanium White'),
  ]);

  type ApiResponseType = typeof apiResponse;
  // type ApiResponseType = [Response, string];
}

with Classes

Classes are values and types, at the same time.

A common use of typeof is to obtain a type representing the static side of a class (meaning: constructor, static properties, and other things not present on an instance of the class).

class Fruit {
  constructor(
    public readonly name: string,
    public readonly mass: number,
    public readonly color: string
  ) {}

  static createBanana() {
    return new Fruit('banana', 108, 'yellow');
  }
}

const MyFruit = Fruit;
// const MyFruit: typeof Fruit;

const banana = Fruit.createBanana();
// const banana: Fruit;

const apple = new Fruit('apple', 98, 'red');
// const apple: Fruit;
  • MyFruit, the class (constructor), is of type typeof Fruit
  • Instances are of type Fruit

From the Intermediate TypeScript course on FEM taught by Mike North.

From the React and TypeScript, v2 course on FEM taught by Steve Kinney.


Last Updated: