简体   繁体   English

从 TypeScript static 方法访问实例类型

[英]Access the instance type from a TypeScript static method

In a static method in a base class, is it possible to name the currently class's instance type?在基础 class 的 static 方法中,是否可以命名当前类的实例类型?

Put another way, can you make this code type check:换句话说,你能不能做这个代码类型检查:

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();
});

Note the use of // @ts-expect-error before lines that should be a type error.注意在应该是类型错误的行之前使用// @ts-expect-error error。 They're highlighted as 'unused' because v has type any rather than the type I'm trying to name here.它们被突出显示为“未使用”,因为v具有any类型,而不是我在此处尝试命名的类型。

TypeScript playground link TypeScript 操场链接

By making the static method generic and constrained by the this param of the static method you can make the type of the class that you call the static method on available. By making the static method generic and constrained by the this param of the static method you can make the type of the class that you call the static method on available. From there, just use the InstanceType operator, like so:从那里,只需使用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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM