Keyof 推断字符串 |键只是字符串时的数字 [英] Keyof inferring string | number when key is only a string

查看:34
本文介绍了Keyof 推断字符串 |键只是字符串时的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我像这样定义了一个 AbstractModel:

I define an AbstractModel like so:

export interface AbstractModel {
   [key: string]: any
}

然后我声明类型Keys:

export type Keys = keyof AbstractModel;

我希望任何具有 Keys 类型的东西都会被单义地解释为一个字符串,例如:

I would expect that anything with the Keys type would be interpreted univocally as a string, for example:

const test: Keys;
test.toLowercase(); // Error: Property 'toLowerCase' does not exist on type 'string | number'. Property 'toLowerCase' does not exist on type 'number'.

这是 Typescript (2.9.2) 的错误,还是我遗漏了什么?

Is this a bug of Typescript (2.9.2), or am I missing something?

推荐答案

根据 TypeScript 2.9 发行说明中的​​定义,如果您对具有字符串索引签名的接口进行 keyof,它将返回字符串和数字的并集

As defined in the Release Notes of TypeScript 2.9, if you keyof an interface with a string index signature it returns a union of string and number

给定一个对象类型X,X的keyof解析如下:

Given an object type X, keyof X is resolved as follows:

如果 X 包含字符串索引签名,keyof X 是字符串、数字和表示类似符号属性的文字类型的联合,否则

If X contains a string index signature, keyof X is a union of string, number, and the literal types representing symbol-like properties, otherwise

如果 X 包含数字索引签名,则 keyof X 是数字和表示类似字符串和类似符号属性的文字类型的联合,否则

If X contains a numeric index signature, keyof X is a union of number and the literal types representing string-like and symbol-like properties, otherwise

keyof X 是表示类似字符串、类似数字和类似符号属性的文字类型的联合.

keyof X is a union of the literal types representing string-like, number-like, and symbol-like properties.

来源

这是因为:JavaScript 在索引对象时将数字转换为字符串:

This is because: JavaScript converts numbers to strings when indexing an object:

[..] 当用数字索引时,JavaScript 实际上会在索引到对象之前将其转换为字符串.这意味着用 100(一个数字)索引和用100"(一个字符串)索引是一样的,所以两者需要保持一致.

[..] when indexing with a number, JavaScript will actually convert that to a string before indexing into an object. That means that indexing with 100 (a number) is the same thing as indexing with "100" (a string), so the two need to be consistent.

来源

示例:

let abc: AbstractModel = {
    1: "one",
};

console.log(abc[1] === abc["1"]); // true

当您只需要字符串键时,您只能像这样从界面中提取字符串键:

When you only want the string keys, then you could only extract the string keys from your interface like so:

type StringKeys = Extract<keyof AbstractModel, string>;

const test: StringKeys;
test.toLowerCase(); // no error

此外,TypeScript 编译器还提供了一个选项来获取 keyof 的 2.9 之前的行为:

Also the TypeScript compiler provides an option to get the pre 2.9 behavior of keyof:

keyofStringsOnly (boolean) 默认 false

keyofStringsOnly (boolean) default false

仅将 keyof 解析为字符串值属性名称(无数字或符号).

Resolve keyof to string valued property names only (no numbers or symbols).

来源

这篇关于Keyof 推断字符串 |键只是字符串时的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆