Learn TypeScript w/ Mike North

Type Queries

June 10, 2021

Table of Contents

Type queries allow us to obtain type information from values, which is an incredibly important capability — particularly when working with libraries that may not expose type information in a way that’s most useful for you

keyof

The keyof type query allows us to obtain type representing all property keys on a given interface

ts
type DatePropertyNames = keyof Date
type DatePropertyNames = keyof Date
Try

Not all keys are strings, so we can separate out those keys that are symbols and those that are strings using the intersection operator (&).

If you remember your geometry, it may be useful to think of this as kind of like a dot product, in that when we use the intersection operator, we’re left only with the sub-part of the keyof Date that also is included by string or symbol, respectively.

ts
type DatePropertyNames = keyof Date
 
type DateStringPropertyNames = DatePropertyNames & string
type DateStringPropertyNames = "toString" | "toDateString" | "toTimeString" | "toLocaleString" | "toLocaleDateString" | "toLocaleTimeString" | "valueOf" | "getTime" | "getFullYear" | "getUTCFullYear" | ... 33 more ... | "getVarDate"
type DateSymbolPropertyNames = DatePropertyNames & symbol
type DateSymbolPropertyNames = typeof Symbol.toPrimitive
Try

Interesting! this Symbol.toPrimitive property is the only non-string. 1

typeof

The typeof type query allows you to extract a type from a value. An example is shown below

ts
async function main() {
const apiResponse = await Promise.all([
fetch("https://example.com"),
Promise.resolve("Titanium White"),
])
 
type ApiResponseType = typeof apiResponse
type ApiResponseType = [Response, string]
}
Try

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

ts
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
Try

MyFruit, the class (constructor) is of type typeof Fruit, where instances are of type Fruit


  1. If you’re curious about this property, try running the following in your terminal node -e "console.log(new Date()[Symbol.toPrimitive]('string'))"



© 2023 All Rights Reserved