【发布时间】:2022-01-26 03:14:46
【问题描述】:
我正在做一个项目,我需要实例化一个特定类的多个副本,但参数不同。我正在创建一个实用函数 withAlteredConstructorArgs 来帮助我解决这个问题,但我无法正确设置类型。
以下是我希望如何使用此实用程序的示例:
const createCycler = withAlteredConstructorArgs(
Cycler,
function reverseElementArgs<T>(elements: Array<T>): [Array<T>] {
return [elements.reverse()];
}
);
const cycler = createCycler(['foo', 'bar', 'baz', 'quux']);
console.log(cycler.get(), cycler.get());
// > should log 'quux', 'baz'
我编写的函数按预期工作,但没有按我预期的方式进行类型检查。我创建了一个TypeScript Playground 来充分演示,但这里是实现:
function withAlteredConstructorArgs<Args extends Array<any>, T>(
c: { new(...args: Args): T },
fn: (...args: Args) => Args
): (...args: Args) => T {
return (...args: Args) => new c(...fn(...args))
}
我认识到我对T 的约束不够,这就是我收到错误消息的原因:'any[]' is assignable to the constraint of type 'Elements', but 'Elements' could be instantiated with a different subtype of constraint 'any[]'。 我了解此错误并已修复它,但不是与类构造函数参数有关的问题。 正确约束T 的构造函数参数的正确语法是什么?
我认识到我可以通过创建工厂函数并从问题陈述中完全删除构造函数来解决这个问题,但我觉得理解这种方法会更好地提高我对 TypeScript 的理解。另外,我用工厂方法打了similar issues,所以看起来构造方法无论如何都是要走的路。
【问题讨论】:
-
有趣的问题。让
withAlteredConstructorArgs为您调用构造函数的动机是什么?const cycler = new Cycler(reverseElementArgs(['foo', 'bar', 'baz', 'quux']));会有同样的效果吗? -
我很想直接调用它,但这是一个服务管理器,它将遍历列表并为列表中的每个配置创建一个新的服务实例。
标签: typescript generics