TypeScript:为什么keyof {}的类型是never?

4

当将keyof操作符应用于空对象时,我感到困惑。以下是示例代码:

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

为什么类型是never?我认为never是永远不会返回的函数的返回类型。难道类型不应该是any[]吗?

像这样更改对象时,类型才有意义:

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

我在实现一个返回对象键名的函数时发现了这个行为:
function getKeys(o: object) {
    return Object.keys(o) as Array<keyof typeof o>;
}

该函数的返回类型应该是(keyof typeof o)[],而不是never[],如果我没错的话。
1个回答

4

编辑:好的,所以,在更新后问题对我来说更清晰了。这里的问题在于你没有使用泛型,所以你实际上是在请求 object 的键,而不是 某个对象 的键。

您可以按照以下方式重新排列函数:

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

这样它将会接受一个类型为 O 的通用对象,此时keyof O的类型将被精确地定义为Array<keyof O>。例如:

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

修改后的答案:

never 表示一个永远不会发生的值,就像在 TS 文档中所解释的那样。这是因为对象中没有键存在。为了更好地理解它,可以参考 TS 文档中的以下陈述:

never 类型是每个类型的子类型,并且可以分配给每个类型;

这意味着,在这种情况下,never 正确地是 string 的子类型,特别表示“没有字符串”,因此“没有键”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接