简体   繁体   English

ES6 mixins的Typescript定义

[英]Typescript definition for ES6 mixins

Is there a way to write a Typescript definition for an ES6 mix-in ? 有没有办法为ES6混合编写Typescript定义?

I've this pattern in library.js , and I'd like to create the library.d.ts 我在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) {}

No, Typescript type system is not expressive enough for that - see the discussion in https://github.com/Microsoft/TypeScript/issues/7225 and https://github.com/Microsoft/TypeScript/issues/4890 . 不,Typescript类型系统对此没有足够的表现力 - 请参阅https://github.com/Microsoft/TypeScript/issues/7225https://github.com/Microsoft/TypeScript/issues/4890中的讨论。

The idiomatic 'type of classes' in typescript is written as 打字稿中惯用的“类型”写成

interface Constructor<T> {
    new (...args): T;
}

So one way to write declaration for Compose is 因此,为Compose编写声明的一种方法是

export declare class Simple {}

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

That is, Compose return type is declared to be a constructor for intersection type - a type which must have all the properties of parameter (Base) together with all the properties of the mixin. 也就是说,Compose返回类型被声明为交集类型的构造函数 - 一种必须具有参数(Base)的所有属性以及mixin的所有属性的类型。

You can use that declaration (assuming it's in the library.d.ts file) like this 你可以像这样使用那个声明(假设它在library.d.ts文件中)

import {Super} from './library'

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

The minor inconvenience is that you always have to provide argument for Super.Compose() because type inference does not work without knowing the value for default parameter, and you can't provide value for default parameter in the declaration file. 稍有不便之处在于您总是必须为Super.Compose()提供参数,因为在不知道default参数值的情况下类型推断不起作用,并且您无法在声明文件中为default参数提供值。

But the big problem is that you can't really use the result of Compose as a class: 但是最大的问题是你无法真正使用Compose的结果作为一个类:

class MyClass extends Super.Compose(Super) {}

does not compile due to the issues mentioned above: 因上述问题而无法编译:

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

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

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