简体   繁体   中英

TypesScript: Why does keyof {} have the type never?

I am confused by the keyof operator when applied to an empty object. Example code:

const o = {};
const k : Array<keyof typeof o> = [];
// k has type never[]

Why is the type never ? I thought never is the return type of functions that never return. Should the type not be any[] instead?

When changing the object like this, the type makes sense:

const o = {a: 1, b: 2};
const k : Array<keyof typeof o> = []; 
// k has the type ("a" | "b")[]

I found this behaviour when implementing a function that returns the typed keys of an object:

function getKeys(o: object) {
    return Object.keys(o) as Array<keyof typeof o>;
}

The function has the return type never[] but should actually have (keyof typeof o)[] if I am correct

EDIT: Ok, so, after the update the questions is clearer to me. The problem here is that you are not using generics, so you are literally asking TS for the keys of object , not of SOME object .

You can re-arrange the function in this way:

function getKeys<O extends {}>(o: O) {
    return Object.keys(o) as Array<keyof O>;
}

So that it will accept a generic object of type O, and in this case keyof O will be typed exactly Array<keyof O> . For example:

const keys = getKeys({ a: 1, b: 2 });
// Now keys has type ("a" | "b")[]

Old answer before post edit:

never represents a value that can never occur, like explained in the TS Doc . This is the case, since there are no keys in the object. To understand it better, this statement from TS Doc may be helpful:

The never type is a subtype of, and assignable to, every type;

This means that, in this case, never is correctly a subtype of string, especially meaning "no string" and so "no key".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM