ES6 mixins的Typescript定义

时间:2016-09-10 20:46:51

标签: javascript typescript ecmascript-6

有没有办法为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 个答案:

答案 0 :(得分:4)

不,打字稿类型系统表达不够 - 请参阅https://github.com/Microsoft/TypeScript/issues/7225https://github.com/Microsoft/TypeScript/issues/4890中的讨论。

习惯性的课程类型'在打字稿中写成

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()提供参数,因为在不知道default参数值的情况下类型推断不起作用,并且您无法在声明文件中为默认参数提供值

但最大的问题是你无法真正将Compose的结果用作一个类:

class MyClass extends Super.Compose(Super) {}
由于上述问题,

无法编译:

error TS2509: Base constructor return type 'Super & {}' is not a class or interface type.