类型“键”不能用于索引 TypeScript 中的类型“对象”

迈克尔

我有一些对象:

const obj = { age: 25, name: "Michal", gender: "Male" }
type Object = typeof obj

然后,我有类型助手,它将从此对象返回指定属性的类型:

type Value<Key extends keyof Object> = Object[Key]

Value<"age"> // number

如果KeyinValue也可以是无效的,我应该怎么做?像这样的东西:

type Value<Key extends void | keyof Object> = Key extends void ? never : Object[Key]

但它不起作用并出现错误:

类型“键”不能用于索引类型“对象”

我该如何解决?

杰卡尔兹

这是目前 TypeScript 的设计限制或缺失功能;有关相关问题,请参阅microsoft/TypeScript#48710microsoft/ TypeScript#26240 (可能还有其他)。

形式的条件类型T extends U ? TrueBranch<T> : FalseBranch<T>可以将类型缩小trueT分支中的约束 ,变成类似. 但是在假分支中没有任何缩小。TypeScript 没有表单的否定类型(这是在microsoft/TypeScript#29317中实现的,但从未发布过),因此在一般情况下无法表达。您只需获得原始的、未缩小的. 在两者和都是文字类型的联合特定情况下,您可以过滤为类似UTrueBranch<T & U>not UFalseBranch<T & not U>FalseBranch<T>TTUTExclude<T, U>,但尚未实施。


幸运的是,有一些解决方法。在像您这样的情况下,您只需要真正Key缩小到keyof Object; 你不关心缩小到void,因为你生产neverif Keyis void您可以简单地反转检查的意义,使真分支和假分支位于不同的位置:

type Value<Key extends void | keyof Object> = 
  Key extends keyof Object ? Object[Key] : never; // okay

当然,在某些情况下,您确实需要在真分支和假分支中都缩小范围,因此您不能简单地交换您正在检查的内容:

type Foo = { x: string, y: number };
type Bar = { a: string, b: number };

type BazBad1<K extends keyof Foo | keyof Bar> =
  K extends keyof Foo ? Foo[K] : Bar[K]; // error!

type BazBad2<K extends keyof Foo | keyof Bar> =
  K extends keyof Bar ? Bar[K] : Foo[K]; // error!

在这些情况下,您可以添加冗余检查以获得所需的行为:

type Baz<K extends keyof Foo | keyof Bar> =
  K extends keyof Foo ? Foo[K] : 
  K extends keyof Bar ? Bar[K] : 
  never; // okay

Playground 代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Typescript中的对象索引键类型

Typescript:类型'undefined'不能用作索引类型.ts(2538)

Typescript错误:元素隐式具有“ any”类型,因为类型“ string”的表达式不能用于索引类型

TypeScript:隐式具有“ any”类型,因为类型“ string”的表达式不能用于索引类型

TypeScript - 元素隐式具有“any”类型,因为“storyFile”类型的表达式不能用于索引类型“{}”

Typescript:作为对象键的并集的类型不能用作该对象的键

map()中的Typescript错误:元素隐式具有“ any”类型,因为类型“ string”的表达式不能用于索引类型

为什么我在TypeScript中遇到“类型'String'不能用作索引类型”错误

内插字符串类型不能用于索引与键类型相同的记录

TypeScript-元素隐式地具有“ any”类型,因为类型“ string”的表达式不能用于索引类型

TypeScript:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型

Typescript中嵌套对象的索引类型

TypeScript中的对象类型转换

TypeScript对象中的查找类型

带有React> Element的Typescript隐式具有'any'类型,因为类型'string'的表达式不能用于索引

类型“ N [P]”不能用于索引类型“ IComponents <N>”

类型'string'不能用于索引类型'T'.ts(2536)

类型“ test”不能用于索引类型“ T”

类型 'string' 不能用于索引类型 'Partial<T>

如何在不忽略TypeScript警告的情况下测试Object是否具有键值:'string'不能用于索引类型?

“字符串”不能用于索引类型“ {}”

如何解决:'string'不能用于索引类型

字符串不能用于索引类型“ T”

使用键名索引 json 对象给出错误 [[keyname]] 不能用于索引类型“对象”

索引类型的TypeScript键太宽

TypeScript中对象文字中的类型定义

如何从TypeScript中的类型化对象中动态删除键

通用类型索引。TS2536:类型“字符串”不能用于索引类型“T”

在 TypeScript 中,如何指定对象中值的类型?