Vespaiach
Vespaiach

Reputation: 65

What does `keyof any` do?

As I know, for any type T, the keyof T will be public property names of T, and then I see keyof any which make me confused. Can I just simplify keyof any to any ?

Upvotes: 5

Views: 332

Answers (1)

jcalz
jcalz

Reputation: 329533

The type keyof any isn't any. It is string | number | symbol:

type PropKey = keyof any
// type PropKey = string | number | symbol

The keyof type operator results in a union of all key types which are known to be allowable for the type. So keyof any is asking for all possible key types, since the any type allows you to index into it with any valid key whatsoever. Not all types are valid keys, though, so keyof any is just string | number | symbol instead of something like the unknown type:

declare const x: any;
x.str; // okay
x[123]; // okay
x[Symbol("")] // okay
x[new Date()] // error
x[false] // error

An equivalent type to keyof any is provided in the TypeScript standard declaration files as PropertyKey:

declare type PropertyKey = string | number | symbol;

Generally speaking you would probably use PropertyKey instead of keyof any, if you're only interested in supporting recent TypeScript versions.

The reason why you might see keyof any is that before TypeScript 2.9, the keyof operator would only return types assignable to string. Starting with TypeScript 2.9, keyof supports number and symbol key types as well. And PropertyKey itself was also introduced in TypeScript 2.9.

That means if you have any TypeScript code which needs to support versions both before and after TypeScript 2.9, you can use neither PropertyKey nor string | number | symbol to properly constrain key types. But you can use keyof any; in TypeScript 2.8 and below, keyof any returns just string, while afterward it returns string | number | symbol. So you can write something like

type DateHolder<K extends keyof any> = { [P in K]: Date };

and it will work in both cases. It's been a while since TypeScript 2.8, though, and many breaking changes have occurred since then, so using keyof any is probably not necessary.

Playground link to code

Upvotes: 5

Related Questions