typescript - 为什么在使用类型映射时必须在“any”类型前面添加“keyof”
问题描述
我想创建新类型,而不是转换特定类型,下面是我的代码:
type CustomMapped<K extends any , T> = { //can't compile
[P in K]: T
};
它没有编译,错误是:
类型 K 不可分配给类型 'string | 号码 | 象征'
所以我必须keyof
在任何前面添加:
type CustomMapped<K extends keyof any , T> = ... //can compile
我很困惑,如果我将代码重写为:
type CustomMapped<K extends string | number | symbol, T> = { //also compile
[P in K]: T
};
它可以编译,所以这意味着 Type K可以分配给 typestring | number | symbol
那么为什么最初的错误说 Type K is not assignable to type string | number | symbol
,为什么我添加了keyof
它就可以了?
解决方案
运算符in
用于创建映射类型。
它期望字符串、数字或符号的联合能够有效地迭代。如文档中所示:
type Keys = 'option1' | 'option2';
type Flags = { [K in Keys]: boolean };
K
将成为option1
第一次“迭代”和option2
第二次。但是,如果Keys
是一个对象,这是行不通的。
type Keys = { option1: any; option2: any };
type Flags = { [K in Keys]: boolean };
// ^^^^
// Type 'Keys' is not assignable to type 'string | number | symbol'.
因为Keys
不是一个string
,number
或者symbol
迭代,而是一个对象。由于我们要遍历键,因此可以使用keyof
操作符来解决这个问题 return 'option1' | 'option2'
。
使用您的示例,您可以更新它,[P in keyof K]
这将评估[P in 'option1' | 'option2']
并按预期工作:
type CustomMapped<K extends any, T> = { [P in keyof K]: T };
推荐阅读
- c++ - 带有文件流的 getline 正在以正则表达式格式捕获行
- c - 如何在 vscode 中为 windows 安装自定义 c 库?
- oracle - 错误“Oracle 主目录包含无效字符”
- qt - 模块“QtQuick.XmlListModel”没有安装?
- javascript - 在 pwa 中禁用右键单击图像
- apache-spark - 我可以像推送 spark 指标一样将 spark 应用配置推送到 prometheus 吗?
- python - 如何在 h5py 中为不同的数据集设置不同的缓存大小?
- python - Python 挑剔的 ListIndexOut of Range
- python - 将两个 python 列表组合成一个笛卡尔积
- rust - 如何使用 Rust 的`catch_unwind` 获取恐慌信息(尤其是堆栈跟踪)?