将对象类型转换为Angulars Type< T> [英] Cast object type to Angulars Type<T>

查看:41
本文介绍了将对象类型转换为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&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆