Typescript,通用可变参数工厂函数返回元组 [英] Typescript, generic variadic factory function returning tuple
问题描述
在打字稿中,可以这样创建工厂函数,并定义返回类型:
In typescript, a factory function can be created like this, with a return type defined:
function factory1<T>(object: new () => T): T {
return new object();
}
如果要创建几个不同的对象,可以将此功能扩展为:
If I want to create several different objects, I can extend this function to:
function factory2<T, U>(object1: new () => T, object2: new () => U): [T, U] {
return [new object1(), new object2()];
}
现在我的问题是:可以将此工厂模式推广为采用任意数量的不相关对象类型,并且仍然返回类型化的元组吗?还是删除强类型并还原为任何类型的唯一选择?
Now to my question: Can this factory pattern be generalized to take any number of unrelated object types and still return a typed tuple? Or is the only option to drop the strong typing and revert to using any?
类似这样的东西:
function factory3<T extends any[]>(...objects: {new(): any}[]): [...T] {
// BODY
}
最后一个问题factory3的问题是我们丢失了T的类型,而是获得了"typeof T".例如:
The issue with the last one, factory3, is that we lose the type of T and instead get "typeof T". For example:
factory3(ClassA, ClassB, ClassC);
// actually becomes this:
factory3<typeof ClassA, typeof ClassB, typeof ClassC>(...) : [typeof ClassA, typeof ClassB, typeof ClassC] {}
// But we want this to happen instead, which is possible for factory 1:
factory3<typeof ClassA, typeof ClassB, typeof ClassC>(...) : [ClassA, ClassB, ClassC] {}
推荐答案
当然,您可以将factory rest参数设为类型断言或类似的东西从而使编译器确信主体中返回的值实际上是 [... T]
:
Sure, you can make the factory rest argument a mapped array/tuple type. You'll need a type assertion or something like it to convince the compiler that the returned value in the body is really a [...T]
:
function factory<T extends any[]>(...ctors: { [K in keyof T]: new () => T[K] }) {
return ctors.map(x => new x) as [...T];
}
您可以验证它是否有效:
You can verify that this works:
class A {
x = 1;
}
class B {
u = "u";
}
class C {
s = true;
}
const objects = factory(A, B, C);
// const objects: [A, B, C]
console.log(JSON.stringify(objects)); // [{"x":1},{"u":"u"},{"s":true}]
这篇关于Typescript,通用可变参数工厂函数返回元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!