首页 > 解决方案 > 从 TypeScript 静态方法访问实例类型

问题描述

在基类的静态方法中,是否可以命名当前类的实例类型?

换句话说,你能不能做这个代码类型检查:

class Base {
  static addInitializer(i: (v: any /* What type would go here? */) => void) {
    // implementation is irrelevent
  }
}

class Dog extends Base {
  bark() {}
}

class Fish extends Base {
  swim() {}
}

Dog.addInitializer((dog) => {
  dog.bark();
  // @ts-expect-error
  dog.swim();
});

Fish.addInitializer((fish) => {
  fish.swim();
  // @ts-expect-error
  fish.bark();
});

注意// @ts-expect-error应该是类型错误的前行的使用。它们被突出显示为“未使用”,因为v具有类型any而不是我在这里尝试命名的类型。

TypeScript 游乐场链接

标签: typescript

解决方案


通过使静态方法通用并受静态方法的this参数约束,您可以使调用静态方法的类的类型可用。从那里,只需使用InstanceType运算符,如下所示:

class Base {
  static addInitializer<T extends new (...args: any) => Base>(this: T, init: (e: InstanceType<T>) => void) {
    // implementation is irrelevent
  }
}

class Dog extends Base {
  bark() {}
}

class Fish extends Base {
  swim() {}
}

Dog.addInitializer((dog) => {
  dog.bark();
  // @ts-expect-error
  dog.swim();
});

Fish.addInitializer((fish) => {
  fish.swim();
  // @ts-expect-error
  fish.bark();
});

推荐阅读