将对象类型转换为Angulars Type< T> [英] Cast object type to Angulars Type<T>
问题描述
我有一个组件列表,一个AnyComponent类型和一个用于查找组件的函数:
I have a list of components, an AnyComponent type, and a function to find a component:
const components = [Comp1, Comp2, Comp3 ...];
type AnyComponent = typeof components[number];
findComponent(id: string): AnyComponent|undefined {
return components.find(comp => comp.id === id);
}
问题是findComponent返回此类型:
The problem is that findComponent returns this type:
typeof Comp1 | typeof Comp2 | typeof Comp3
但是我需要使用的下一个函数(角度resolveComponentFactory)要求它为 Type< AnyComponent>
或 Type< typeofComp1 | |.Comp2的类型|Compof的类型>
But the next function i need to use (angulars resolveComponentFactory) requires it to be a Type<AnyComponent>
or Type<typeof Comp1 | typeof Comp2 | typeof Comp3>
如果我将findComponent的返回值设置为 Type< AnyComponent>
,则会收到一条错误消息,指出其不可分配.
If i set the return value of findComponent to Type<AnyComponent>
I get an error saying its not assignable.
但是,如果我将AnyComponent更改为此:
However if i change AnyComponent to this:
type AnyComponent = Comp1 | Comp2 | Comp3;
然后我只能将findComponent返回值设置为 Type< AnyComponent>
,并且一切正常.
then only can i set findComponent return value to Type<AnyComponent>
, and it all works.
使用联合工作的所有问题在于,我必须对每个组件声明两次,而我确实在寻找一种只定义一次的方法.
The problem with it all working using a union is that I have to declare each component twice and I'm really looking for a way to define them only once.
那么有没有办法让findComponent返回 Type< AnyComponent>
?
So is there a way to have findComponent return Type<AnyComponent>
?
推荐答案
AnyComponent
包含类类型的并集(即 typeof Comp1
). Type< T>
中的 T
期望 T
是实例类型(即 Comp1
).幸运的是,Typescript具有 InstanceType< T>
来从类类型中提取实例类型.
AnyComponent
contains a union of the class types (ie typeof Comp1
). T
in Type<T>
expects T
to be the instance type (ie Comp1
). Fortunately Typescript has InstanceType<T>
to extract the instance type from a class type.
我们可能希望我们可以做到 Type< InstanceType< AnyComponent>>
,但由于类型为 new(... args:any [])=>T
会导致
We might expect we can do Type<InstanceType<AnyComponent>>
but since the definition of type new (...args: any[]) => T
this would result in
Type<InstanceType<AnyComponent>> == new (...args: any[]) => Comp1 | Comp2 | Comp3
不能从 Comp1
分配的
,我们想要的是将实例联合以 Type< T>
的联合分配,为此,我们需要一个条件类型:
which is not assignable from Comp1
, what we want is to distribute the instance union in a union of Type<T>
and for this we need a conditional type:
// Dummy
class Comp1 { static id:string; private s: string}
class Comp2 { static id:string; private s: string}
class Comp3 { static id:string; private s: string}
type Type<T> = new (...args: any[]) => T;
const components = [Comp1, Comp2, Comp3];
type AnyComponent = typeof components[number];
// Conditional type to transform the union of instance type into a union of Type<T>
type TypeUnion<T> = T extends any ? Type<T> : never;
function findComponent(id: string): TypeUnion<InstanceType<AnyComponent>>|undefined {
return components.find(comp => comp.id === id);
}
这篇关于将对象类型转换为Angulars Type< T>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!