ES6混入类型的TypeScript定义

5

有没有一种方法可以为 ES6 mix-in编写Typescript定义?

我在library.js中有这个模式,我想创建library.d.ts

// declaration in `library.js`
class Super extends Simple {
    constructor() {}

    static Compose(Base = Super) {
        return class extends Base {
            // ...    
        }

    }
}

// usage in `client.js`
class MyClass extends Super.Compose() {}
let myInstance = new MyClass();

class MyOtherClass extends Super.Compose(AnotherClass) {}
1个回答

4
不,TypeScript 类型系统并不足够表达这个 - 参见 https://github.com/Microsoft/TypeScript/issues/7225https://github.com/Microsoft/TypeScript/issues/4890 中的讨论。
TypeScript 中惯用的“类的类型”写法为:
interface Constructor<T> {
    new (...args): T;
}

因此,编写Compose声明的一种方法是

export declare class Simple {}

export declare class Super extends Simple {
    static Compose<T>(Base?: Constructor<T>): Constructor<T & {/*mixed-in declarations*/}>
}

也就是说,Compose 的返回类型被声明为交叉类型的构造函数 - 这种类型必须具有参数(Base)的所有属性以及 mixin 的所有属性。您可以像这样使用该声明(假设它在 library.d.ts 文件中):
import {Super} from './library'

let MyComposed = Super.Compose(Super)
let myInstance = new MyComposed

小小的不便是,你总是需要为Super.Compose()提供参数,因为类型推断无法在不知道默认参数值的情况下工作,并且你不能在声明文件中提供默认参数值。
但是大问题是你不能真正将Compose的结果用作类:
class MyClass extends Super.Compose(Super) {}

由于上述问题,代码无法编译:
error TS2509: Base constructor return type 'Super & {}' is not a class or interface type.

非常好的解释,谢谢。现在正在跟踪 https://github.com/Microsoft/TypeScript/issues/4890。 - trefeater
在 https://github.com/therror/therror 中,这是通过导出混合返回类的形状来实现的,开发者必须在代码中定义新的形状 https://github.com/therror/therror#typescript-limitations - trefeater

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接