typescript - 为什么`typeof Map2` 返回“数字”的提示?
问题描述
代码很简单。这是 TS 或 VScode 的错误吗?
interface Map2<T> {
[key: string]: T;
}
type XXX = keyof Map2<string>
//hint~ type XXX = string | number
interface Map2<T> {
[key: string]: T;
}
type XXX = keyof Map2<boolean>
//hint~ type XXX = string | number
解决方案
这不是一个错误。这种行为是在 TypeScript 2.9 中引入的。从文档中:
给定一个对象类型
X
,keyof X
解析如下:
- 如果
X
包含字符串索引签名,keyof X
是 , 和表示符号类属性的文字类型的string
并number
集
这样做的原因是为了处理 TypeScript 具有number
键概念的事实,尽管 JavaScript 确实没有。但是 TypeScript假装它number
是对象的有效键类型。
JavaScript 中的所有非符号键实际上都是字符串,甚至是数组的索引键。(例如,Object.keys(["a","b"])
返回["0", "1"]
)当您使用数字索引到数组时,如在中arr[0]
,索引首先被强制转换为字符串并被视为arr["0"]
。因此,具有string
索引的对象仍然可以被视为具有数字键的类数组对象,因为string
当您使用它们时它们将被强制转换。
在一个完全健全和理想的 TypeScript 类型系统中,会有一个名为NumericString
的类型,它是string
对应于 的String(n)
所有number
值的输出的子类型n
。当你用它索引一个对象时,TypeScript 会自动强制number
执行。NumericString
在那个假设的世界中,string
索引只是一个string
索引,您仍然可以像使用数组一样使用它,并且没有任何人想要添加number
到keyof {[k: string]: any}
.
然而,在这个世界中,数组在 TypeScript 中表示为具有number
键,如果您只将键视为非键,则会出现问题。你会得到是。他们没有通过删除索引并将它们更改为来修复它,而是通过添加作为伪子类型来解决它,该伪子类型仅在您查看对象键时出现。string
number
keyof {[n: number]: any}
never
number
NumericString
number
string
所以,你去吧。这是故意的。如果您不想在 中看到number
,string
可以使用建议的解决方法替换keyof X
为Extract<keyof X, string>
.
好的,希望有帮助;祝你好运!
推荐阅读
- azure - Azure 服务总线,使用 SDK 检查 ASB 是否受到限制
- c - 在 VSCode 中使用 gcc 编译 C 程序时出错
- javascript - 当 source 在 document.implementation.createHTMLDocument 对象中时,canvas getImageData 对于图像是黑色的
- python - 导入 numpy 并调用 Fortran 库时出现分段错误
- botframework - 用相同的话语训练后未检测到 LUIS 实体
- python - 如何制作分组条形图
- swift3 - 在 UIPageViewController 中调整实例化视图控制器的大小?
- javascript - Highcharts 中按月分类的分类
- amazon-web-services - AWS API Gateway - 根据分钟而不是秒来限制请求。
- php - PHP)如何使json多个数组?