如何创建在TypeScript中返回mixin函数的函数? [英] How to create function that returns mixin function in TypeScript?

查看:26
本文介绍了如何创建在TypeScript中返回mixin函数的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试将 Polymer.dedupingMixin ES6函数转换为TypeScript.我不确定是否有可能.

I try to convert Polymer.dedupingMixin ES6 function to TypeScript. I don't sure it's possible or not.

https://github.com/Polymer/polymer/blob/v2.0.2/lib/utils/mixin.html

通常,TypeScript 2.2+可以正确地用于基本的mixin函数,例如以下代码.

Normally, TypeScript 2.2+ can work correctly for basic mixin function like the following code.

type IConstructable = new (...args: any[]) => object;

function extendClass<T extends IConstructable>(baseClass: T) {
    return class extends baseClass {
        instanceMethod_DynamicClass() { }
        static staticMethod_DynamicClass() { }
    }
}

class Test {
    instanceMethod_TestClass() { }
    static staticMethod_TestClass() { }
}

var d3 = extendClass(Test);
d3.staticMethod_DynamicClass();
d3.staticMethod_TestClass();

var d4 = new d3();
d4.instanceMethod_DynamicClass();
d4.instanceMethod_TestClass();

我尝试创建一些类似于此声明功能的功能.

I try to create some function like this declaration fuction.

declare function extendClass<T extends IConstructable>(baseClass: T): {
    new (...args: any[]): {
        instanceMethod_DynamicClass(): void;
    };
    staticMethod_DynamicClass(): void;
} & T;

我的TypeScript代码看起来像下面的代码.它不能正常工作.我尝试在许多地方修改通用类型.但这仍然行不通.

My TypeScript code looks like the following code. It doesn't work correctly. I try modify generic type in many places. But it's still not work.

interface IConstructable<T> {
    new(...args: any[]): T;
}

function extendClass<T extends IConstructable<T>, TExtended extends IConstructable<TExtended>>(mixin: (base: T) => TExtended & T) {
    return function <T, TExtended>(base: T) {
        return mixin(base);
    };
}

class Test {
    instanceMethod_TestClass() { }
    static staticMethod_TestClass() { }
}

class Test2 {
    instanceMethod_TestClass() { }
    static staticMethod_TestClass() { }
}

var propEffect = extendClass(superClass => {    
    return class internalClass extends superClass {
        instanceMethod_ExtendedClass() { }
        static staticMethod_ExtendedClass() { }
    }
});

var d3 = propEffect(Test) ;
d3.staticMethod_ExtendedClass();
d3.staticMethod_TestClass();

var d4 = new d3();
d4.instanceMethod_ExtendedClass();
d4.instanceMethod_TestClass();

推荐答案

我不太明白为什么需要 extendClass(),因为它本质上是身份函数(它使用mixin作为一个参数并返回具有相同行为的mixin),那么您可以像这样实现它,而在其余代码中没有错误:

I don't quite understand why you need extendClass(), since it is essentially the identity function (it takes a mixin as a parameter and returns a mixin with the same behavior), and you could implement it like this with no errors in the rest of the code:

function extendClass<M>(mixin: M): M {
  return mixin;
}

假设您需要 extendClass()的签名来明确表明它仅接受mixin,则可以这样做.为mixins使用类型别名会有所帮助:

Assuming you need the signature of extendClass() to explicitly indicate that it only accepts mixins, you can do so. It helps to have a type alias for mixins:

type Mixin<X extends IConstructable<{}>> = <T extends IConstructable<{}>>(baseClass: T) => T & X;

阅读: Mixin< ExtendedClassConstructor> 是一个采用通用基类构造函数并返回既是基类构造函数又是 ExtendedClassConstructor 的函数的函数.

Read: a Mixin<ExtendedClassConstructor> is a function which takes a generic base class constructor and returns something which is both a base class constructor and an ExtendedClassConstructor.

现在,您可以按以下方式实现 extendClass():

Now you can implement extendClass() as follows:

function extendClass<X extends IConstructable<{}>>(mixin: Mixin<X>): Mixin<X> {
  return mixin;
}

不幸的是,现在当您在箭头函数上调用 extendClass()时,TypeScript不够聪明,无法推断 X 的类型. X 应该是 internalClass ,但是您不能引用它,因为它不在范围内.您需要定义一个与 internalClass 相同形状的适当类型:

Unfortunately, now TypeScript is not clever enough to infer the type of X when you call extendClass() on the arrow function. X should be internalClass, but you can't refer to it since it's not in scope. You need to define an appropriate type with the same shape as internalClass:

type InternalClass = {
  new(...args: any[]): {
    instanceMethod_ExtendedClass(): void;
  }
  staticMethod_ExtendedClass(): void;
}

,然后您最终可以调用 extendClass(),注意将箭头函数输入为mixin:

and then you can finally call extendClass(), being careful to type the arrow function as a mixin:

var propEffect = extendClass<InternalClass>(<T extends IConstructable<{}>>(superClass: T) => {
  return class internalClass extends superClass {
    instanceMethod_ExtendedClass() { }
    static staticMethod_ExtendedClass() { }
  }
});

这一切都应与没有错误,尽管我不确定这对您来说是否值得.希望它能帮助您取得进步.

This should all work with no errors, although I'm not sure if it's worth it for you. Hope it helps you make progress.

这篇关于如何创建在TypeScript中返回mixin函数的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆