最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypesScript: Why does keyof {} have the type never? - Stack Overflow

programmeradmin1浏览0评论

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

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

Share Improve this question asked Apr 27, 2020 at 17:24 Simon HessnerSimon Hessner 1,8372 gold badges27 silver badges51 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

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".

发布评论

评论列表(0)

  1. 暂无评论