sidoshi
sidoshi

Reputation: 2160

Why does `keyof any` have type of `string | number | symbol` in typescript?

The type Record in typescript is defined as:

type Record<K extends keyof any, T> = {
    [P in K]: T;
}

I don't understand why keyof any is used here.

After checking I found that the type of keyof any is string | number | symbol. Why is that?

Upvotes: 28

Views: 9842

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250106

keyof any represents the type of any value that can be used as an index to an object. Currently you can use string or number or symbol to index into an object.

let a: any;
a['a'] //ok
a[0] // ok
a[Symbol()] //ok
a[{}] // error

In the Record type, this K extends keyof any is used to constrain K to something that is a valid key for an object. So K could be 'prop' or '1' or string but not {a : string}:

type t0 = Record<1, string> // { 1: string }
type t1 = Record<"prop", string> // { prop: string }
type t3 = Record<string, string> // { [name: string]: string }
type t4 = Record<number, string> // { [name: number]: string }
type t5 = Record<{a : string}, string> // error

The constraint is there, since whatever type is passed in K will become the keys of the resulting type, and thus K must be something that is a valid key for an object.

Upvotes: 33

Related Questions