我有一个令人费解的案例,我有99%的肯定使用typescript无法解决,而且问题很明显是因为将Typescript代码与不安全的JS代码连接在一起。但是我之前见过在这个网站上发生过奇迹……
我有一些我无法控制但必须使用的JS代码,它采用一个自动生成的抽象类(来自protobuf定义,但这并不重要)进行扩展并创建它。自动生成的类具有d.ts
个文件,这是重要的部分,因为我想保留其类型信息以用于自动完成。
因此,让我们从包装扩展并创建抽象类的JS代码开始->
type getCtorType<Ctor> = Ctor extends { new(): infer T } ? T : never;
const initalizeClass = <Ctor extends { new(): any }>(abstractCtor: Ctor): getCtorType<Ctor> => {
return null as any; //In reality, here there is a call to javascript code that does all the magic
}
因此,举例来说,我有两个类,一个是抽象的,另一个不是:
class Foo {
someFunc(a: string) {}
}
abstract class Bar {
someFunc(a: string) { };
}
我们将其初始化:
//This has type inference;
const instance1 = initalizeClass(Foo);
//This is an error
const instance2 = initalizeClass(Bar);
第二行失败,因为抽象类无法满足{ new (): any}
的约束,因为它无法创建。
如果我从initalizeClass
中删除了此约束,而改用Function
之类的东西
const initalizeClassAlternative = (abstractCtor: Function) => {
return null as any; //In reality, here there is a call to javascript code that does all the magic
}
如果这样做,我将丢失所有类型推断。
有人能想到一种方法/技巧来从传递给函数的抽象类中提取类型吗?以与如何提取常规类的类型类似的方式?
如果您想知道为什么这样的功能还不够好,我真的想输入推断:
const instance2: Bar = initalizeClassAlternative(Bar);
这里是playground link。这个例子更接近我的实际用例,因为这个问题已经太长了,我将其删掉了……但是总之,我正在尝试使用映射类型。
答案 0 :(得分:1)
在有type inference in conditional types之前,有lookup types。根据{{3}},Function
接口具有类型prototype
的{{1}}属性。类(甚至是抽象类)将使用与所讨论类的实例类型相对应的类型来覆盖此属性。因此,作为解决问题的快速方法,您可以检查以下属性:
any
(出于您可能并不在意的美学原因,我将名称从type InstanceType<Ctor> = Ctor extends Function ? Ctor['prototype'] : never;
更改为getCtorType<>
,请随时将其改回。)
这使您可以使用第二种方法:
InstanceType<>
对我很好!如果您想排除将非类似declare const initalizeClass: <Ctor extends Function>(
abstractCtor: Ctor
) => InstanceType<Ctor>;
abstract class Bar {
someFunc(a: string) { };
}
const bar = initalizeClass(Bar);
bar.someFunc("works");
的{{1}}类型传递到class
(例如,要求Function
属性不为{{1} }),但可能没有必要。
希望有所帮助;祝你好运!