我有一些对象:
const obj = { age: 25, name: "Michal", gender: "Male" }
type Object = typeof obj
然后,我有类型助手,它将从此对象返回指定属性的类型:
type Value<Key extends keyof Object> = Object[Key]
Value<"age"> // number
如果Key
inValue
也可以是无效的,我应该怎么做?像这样的东西:
type Value<Key extends void | keyof Object> = Key extends void ? never : Object[Key]
但它不起作用并出现错误:
类型“键”不能用于索引类型“对象”
我该如何解决?
这是目前 TypeScript 的设计限制或缺失功能;有关相关问题,请参阅microsoft/TypeScript#48710和microsoft/ TypeScript#26240 (可能还有其他)。
形式的条件类型T extends U ? TrueBranch<T> : FalseBranch<T>
可以将类型缩小到trueT
分支中的约束 ,变成类似. 但是在假分支中没有任何缩小。TypeScript 没有表单的否定类型(这是在microsoft/TypeScript#29317中实现的,但从未发布过),因此在一般情况下无法表达。您只需获得原始的、未缩小的. 在两者和都是文字类型的联合的特定情况下,您可以过滤为类似U
TrueBranch<T & U>
not U
FalseBranch<T & not U>
FalseBranch<T>
T
T
U
T
Exclude<T, U>
,但尚未实施。
幸运的是,有一些解决方法。在像您这样的情况下,您只需要真正Key
缩小到keyof Object
; 你不关心缩小到void
,因为你生产never
if Key
is 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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句