typescript - 如何制定强制通用类实例适合给定接口的约束?
问题描述
有这个代码:
interface Class {
new(...args: any[]): any;
}
class Wrapper<C extends Class> {
asInterface<InstanceType<C> extends I>(): I { // this is where the constraint should go
return undefined as any as I; // this is not important
}
}
interface Plane {
takeoff(): void;
}
interface Car {
drive(): void;
}
class F35B {
takeoff() {
console.log('doing vertical takeoff');
}
shoot() {
console.log('bang bang');
}
}
const w = new Wrapper<typeof F35B>();
const plane = w.asInterface<Plane>(); // this should pass
const car = w.asInterface<Car>(); // this should not
如何对 asInterface 方法设置约束,使我成为构造函数 C 的实例的扩展?
当然,表达式InstanceType<C> extends I
不符合打字稿,但这是问题的关键思想。
解决方案
Typescript 执行此操作的方法不是I
作为通用参数传递,而是将赋值注释为const plane: Plane = ...
,如果不可赋值,则让 Typescript 出错。
我还做了另外两个更改。首先是您的Class
接口需要在实例类型上是通用的,否则new
不会返回正确的类型。第二个是您Wrapper
需要在运行时接受包装的构造函数,它不能只调用new
泛型参数C
,因为泛型在运行时被删除。
所以我认为最终的结果会是这样的:
interface Class<I> {
new(...args: any[]): I;
}
class Wrapper<C extends Class<InstanceType<C>>> {
constructor (private Wrapped: C) {} // <---- `C` is inferred
create () { return new this.Wrapped() }
}
interface Plane {
takeoff(): void;
}
interface Car {
drive(): void;
}
class F35B {
takeoff() {
console.log('doing vertical takeoff');
}
shoot() {
console.log('bang bang');
}
}
const w = new Wrapper(F35B); // <---- Pass constructor at runtime
const plane: Plane = w.create(); // OK
const car: Car = w.create(); // Error
// ~~~
// Property 'drive' is missing in type 'F35B' but required in type 'Car'
推荐阅读
- go - 在 Terraform 中申请后如何知道提供者何时完成
- c++ - OpenSSL 没有共享密码
- tensorflow - tf 如何从同一个变量中恢复两个变量
- python - Cython“无法获取 memoryview 切片的地址”
- c# - 如何获取响应正文以及如何使用 HttpURLConnection 类设置请求正文?
- spring - 如何处理假客户端连接超时
- mongodb - MongoDB 上的时区查询
- java - 通过多种意图正确传递价值
- javascript - 预定义函数 display() 时如何覆盖效果并更改数组每个元素中的效果
- mongodb - 我需要使用操作更新 Mongodb Shell 中的值