Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 800
sidoshi Avatar asked Apr 05 '19 12:04

sidoshi


People also ask

What does Keyof typeof mean in TypeScript?

keyof is a keyword in TypeScript which is used to extract the key type from an object type.

What is key string ]: Any in TypeScript?

The {[key: string]: any} syntax is an index signature in TypeScript and is used when we don't know all the names of a type's properties and the shape of their values ahead of time. The index signature specifies that when an object is indexed with a string, it returns a value with any type.

What is typeof in TypeScript?

TypeScript adds a typeof operator you can use in a type context to refer to the type of a variable or property: let s = "hello"; let n : typeof s ; let n: string. This isn't very useful for basic types, but combined with other type operators, you can use typeof to conveniently express many patterns.

How do you define a type of key of an object in TypeScript?

Use the keyof typeof syntax to create a type from an object's keys, e.g. type Keys = keyof typeof person . The keyof typeof syntax returns a type that represents all of the object's keys as strings.


1 Answers

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.

like image 168
Titian Cernicova-Dragomir Avatar answered Oct 11 '22 09:10

Titian Cernicova-Dragomir