Typescript 带有联合的条件映射类型使函数不可调用 type Container=T扩展任何[]?ArrayContainer:ObjectContainer 类型ArrayContainer={ 集合(arr:T,索引:编号):无效 } 类型ObjectContainer={ 集合(对象:T):无效 } const testContainer={}作为任意容器 //不编译 testContainer.set(33)
条件类型决定返回一个Typescript 带有联合的条件映射类型使函数不可调用 type Container=T扩展任何[]?ArrayContainer:ObjectContainer 类型ArrayContainer={ 集合(arr:T,索引:编号):无效 } 类型ObjectContainer={ 集合(对象:T):无效 } const testContainer={}作为任意容器 //不编译 testContainer.set(33),typescript,Typescript,条件类型决定返回一个ObjectContainer | ObjectContainer,使得无法对ObjectContainer调用任何函数 有没有办法强制返回ObjectContainer 使用可用的最新2.8版本。似乎需要额外的类型参数 type Container<T> = T extends any[] ? ArrayContainer<T> : ObjectContainer<T> type ArrayContainer<T> = {
ObjectContainer | ObjectContainer
,使得无法对ObjectContainer调用任何函数
有没有办法强制返回ObjectContainer
使用可用的最新2.8版本。似乎需要额外的类型参数
type Container<T> = T extends any[] ? ArrayContainer<T> : ObjectContainer<T>
type ArrayContainer<T> = {
set(arr: T, index: number): void
}
type ObjectContainer<T> = {
set(obj: T): void
}
const testContainer = {} as any as Container<{ boxedNumber: number } | number>
// Does not compile
testContainer.set(33)
type Container=T扩展任何[]?ArrayContainer:ObjectContainer;
类型ArrayContainer={
集合(arr:T,索引:编号):无效
}
类型ObjectContainer={
集合(对象:T):无效
}
const testContainer={}作为容器;
testContainer.set(10);
问题在于,条件类型将迭代联合中的类型,并将条件应用于联合中的每个项目并联合结果,因此Container
的结果将等同于ObjectContainer | ObjectContainer
而不是ObjectContainer
您可以创建一个交叉点类型的容器
和容器,其行为与您期望的容器
const testContainer={}与Container和Container一样
testContainer.set(33)
testContainer.set({boxedNumber:19})
正如@TitianCernicovaDragomir所指出的,您的问题是T中带有裸类型参数T
的条件类型扩展了XXX?YYY:ZZZ
最终分布在T
中的一个联合体上。这是,但有一个用于它的:“框”将T
和XXX
放入一个元组,如[T]扩展[XXX]?YYY:ZZZ
。这使得条件不依赖于裸类型参数,并且不再分解联合。(任何T
在协变位置结束的地方都应该工作…{a:T}扩展{a:XXX}
也可以工作)。这很可能会继续工作并得到支持,因为他是推荐它的人,并且是打字脚本中的那个人
所以在你的情况下,你会这样做
const testContainer = {} as any as Container<{ boxedNumber: number }> & Container<number>
testContainer.set(33)
testContainer.set({ boxedNumber: 19})
type Container=[T]扩展了[any[]?ArrayContainer:ObjectContainer
它将把Container
解释为ObjectContainer
,如您所愿
但请注意,现在将容器
解释为对象容器
,因为字符串| number[]
本身不是数组。可以吗?是否应该是ObjectContainer | ArrayContainer
?或者ObjectContainer和ArrayContainer
?还是别的什么?不确定
希望有帮助;祝你好运。如果OP想阻止条件分布在联合体上,事实上的标准方法是将条件“装箱”到一个元组中,如
type Container=[T]extends[any[]?ArrayContainer:ObjectContainer
@jcalz我不知道:)10x。你能补充一下答案吗,它是你的:)?@jcalz噢,哇,我从来没有想到过。不管怎样,它还是有效的!这在未来打破的可能性有多大?如果你发布答案,我很高兴批准。嗯,好的,当然,让我查找文档,然后发布答案。我通常使用类似于T[number&keyof T]
的方法来解决这个问题。或者你可以做丑陋的[T]扩展[any[]?(T扩展任何[]?T[数字]:从不):代码>难道你没有忘记实际的解决方案类型容器=[t]扩展了[any[]?ArrayContainer:ObjectContainer
?我认为只有纯数组才能进入ArrayContainer,任何联合都可以进入ObjectContainer
const testContainer = {} as any as Container<{ boxedNumber: number }> & Container<number>
testContainer.set(33)
testContainer.set({ boxedNumber: 19})
type Container<T> = [T] extends [any[]] ? ArrayContainer<T> : ObjectContainer<T>