1

我正在尝试创建一个触发类init方法并返回实例化类的函数,但我无法保留构造函数和类类型。

我试过了:

class Test {
  constructor(a: number, b: string, c?: number[]) {}

  protected init() {}
}

export function instantiateWithInit<Type extends new (args: any) => { init: () => any }>(
  clazz: new (args: ConstructorParameters<Type>) => InstanceType<Type>,
  ...args: ConstructorParameters<Type>
) {
  const instance = new clazz(args);
  instance.init();
  return instance;
}

instantiateWithInit(Test, "");

但是类型返回只返回init方法,我也有参数不匹配类型构造函数的错误:

Argument of type 'typeof Test' is not assignable to parameter of type 'new (args: [args: any]) => { init: () => any; }'.
  Types of construct signatures are incompatible.
    Type 'new (a: number, b: string, c?: number[]) => Test' is not assignable to type 'new (args: [args: any]) => { init: () => any; }'.ts(2345)
4

1 回答 1

0

这里的问题之一是您的函数期望构造函数只接受一个参数。使用扩展运算符,可以修复这个特定的错误。

为了让你的想法真正发挥作用,我不得不像这样重写函数定义:


class Test {
    constructor(a: number, b: string, c?: number[]) { }

    public init() { }
}

export function instantiateWithInit<
    T extends { init(): any },
    A extends any[]
>(
    clazz: new (...args: A) => T,
    ...args: A
) {
    const instance = new clazz(...args);
    instance.init();
    return instance;
}

const abc = instantiateWithInit(Test, 5, "");
// ^ abc is of type Test
// Also the arguments are checked (hence I needed to add that 5)

我不得不承认,TypeScriptextends在函数定义方面可能会很棘手。

于 2021-07-19T17:35:26.670 回答