function setDictionary<T>( data: T, label: keyof T, dictionaryOptions: { [key in keyof T]: { [key: string | number]: any }[] }) { const options = dictionaryOptions[label];}
options
怎么会是这个类型?应当是{ [key: string | number]: any }[]
才对啊。
是哪里出了问题?如何解决呢?
"vue-tsc": "^1.8.27"
本质问题是
type a = { [key: string | number]: any }
显示为
type c = { [key: string]: any; [key: number]: any;}
因为 JS 中不存在数字类型的Key, 即使取值时数字也会被转为字符串, 所以不存在key的类型是 string | number
ts 会拆分成独立的索引类型,更能描述js 的行为
dictionaryOptions: { [key in keyof T]: Record<string | number, any>[] }
看了下如果这里是一个精确类型就能推导出来
type Data = { name: string, age: string }function setDictionary( data: Data, label: keyof Data, dictionaryOptions: { [key in keyof Data]: { [key: string | number]: any }[] }) { const options = dictionaryOptions[label];}
但如果是泛型就不行,不知道是刻意没有处理这种情况还是 vscode 插件的问题
在 TypeScript 中,类型推断的规则相当复杂,这里涉及到了一些高级的类型推断技巧。让我们首先理解一下你的函数和代码中的类型推断是如何工作的。
首先,label
的类型是 keyof T
,这意味着 label
是 T
类型的键。然后,你试图从 dictionaryOptions
对象中获取与 label
对应的值。
dictionaryOptions
是一个映射类型,它的键是 T
类型的键,值是 { [key: string | number]: any }[]
类型的数组。
当你尝试从 dictionaryOptions
中获取与 label
对应的值时,TypeScript 会尝试推断出这个值的类型。
由于 label
是 keyof T
类型,并且 dictionaryOptions
的键也是 keyof T
类型,TypeScript 可以推断出 options
的类型是 { [key: string | number]: any }[]
。
这个推断是基于 TypeScript 的映射类型和索引签名的推断规则。当你有一个映射类型和一个索引操作时,TypeScript 会使用映射类型的对应规则来推断结果类型。
在你的例子中,映射类型是 { [key in keyof T]: { [key: string | number]: any }[] }
,这意味着对于任何 K in keyof T
,如果我们在该映射上使用一个索引操作 dictionaryOptions[K]
,那么结果类型将是 { [key: string | number]: any }[]
。
因此,当你使用 label
作为索引来获取 options
时,TypeScript 推断出 options
的类型是 { [key: string | number]: any }[]
,这是正确的。
所以,options
的类型并不是你预期的 { [key: string | number]: any }[]
,而是正确的类型。如果你想确保 options
的类型是你期望的类型,你可能需要重新考虑你的函数设计或使用类型断言来明确指定你期望的类型。
TypeScript 类型检查机制包含三个部分: 类型推断 类型保护 类型兼容性 本节介绍其中的类型推断,类型推断主要用于那些没有明确指出类型的地方帮助确定和提供类型,这是 TypeScript 的一种能力。 类型推断是有方向的,要注意区分从左向右和从右向左两种推断的不同应用。 1. 慕课解释 类型推断的含义是不需要指定变量类型或函数的返回值类型,TypeScript 可以根据一些简单的规则推断其
想实现value是string那么val就是string,value是string[]那么val就是string[]
定义一个类型 条件1:变量类型是一个字符串。 条件2:变量值不是 get "typescript": "~5.2.2"
本节介绍类型断言,有使用关键字 as 和标签 <> 两种方式,因后者会与JSX 语法冲突,建议统一使用 as 来进行类型断言。 1. 慕课解释 TypeScript 允许你覆盖它的推断,毕竟作为开发者你比编译器更了解你写的代码。 类型断言主要用于当 TypeScript 推断出来类型并不满足你的需求,你需要手动指定一个类型。 2. 关键字 as 当你把 JavaScript 代码迁移到 TypeS
编辑:OK,在typescript规范中有详细说明:类型断言