Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在TypeScript中实现mixin而不使用任何类型_Typescript_Mixins - Fatal编程技术网

在TypeScript中实现mixin而不使用任何类型

在TypeScript中实现mixin而不使用任何类型,typescript,mixins,Typescript,Mixins,我正在与创建TypeScript代码的混搭程序争论: function applyMixins(derivedCtor: Function, constructors: Function[]) { //Copies methods constructors.forEach((baseCtor) => { Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { Ob

我正在与创建TypeScript代码的混搭程序争论:

function applyMixins(derivedCtor: Function, constructors: Function[]) {
    //Copies methods
    constructors.forEach((baseCtor) => {
      Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
        Object.defineProperty(
          derivedCtor.prototype,
          name,
          Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
            Object.create(null)
        );
      });
    });
    //Copies properties
    constructors.forEach((baseCtor) => {
      let empty = new baseCtor();
      Object.keys(empty).forEach((name) => {
        Object.defineProperty(
          derivedCtor.prototype,
          name,
          Object.getOwnPropertyDescriptor(empty, name) ||
            Object.create(null)
        );
      });
    });
  }
它没有编译,抱怨这一行:
let empty=new baseCtor()
TS2351:此表达式不可构造。类型“Function”没有构造签名。
。我知道这可以通过将第一行中的
函数
类型引用与
任何
进行交换来解决,但我正试图在没有
任何
的情况下生活,因为告诉TypeScript闭嘴通常是一种草率的方式


有没有一种方法可以在不使用
any
的情况下实现此代码?

问题是
函数
是一种非常广泛的类型,包括任何函数,包括不能通过
new
调用的函数。因此,编译器抱怨
函数
不可构造。因此,解决方案是使用已知具有。在TypeScript中,这种签名通过在函数签名前加上关键字
new
来表示:

type NewableFunctionSyntax = new () => object;
type NewableMethodSyntax = { new(): object };
这些类型都表示一个不接受任何参数的构造函数,并生成一个类型为assignable
object
的实例。注意,虽然这些语法不同,但本质上是相同的。(要了解这一点,请注意,编译器允许您多次声明
var
,但如果您使用不同的类型对其进行注释,则会发出抱怨。事实上,以下编译器编译时没有错误

var someCtor: NewableFunctionSyntax;
var someCtor: NewableMethodSyntax; // no error
表示编译器将
NewableFunctionSyntax
NewableMethodSyntax
视为基本可互换。)


通过将
函数
更改为以下选项之一,您的代码现在可以编译而不出错:

function applyMixins(derivedCtor: { new(): object }, constructors: { new(): object }[]) {
    //Copies methods
    constructors.forEach((baseCtor) => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
            Object.defineProperty(
                derivedCtor.prototype,
                name,
                Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
                Object.create(null)
            );
        });
    });
    //Copies properties
    constructors.forEach((baseCtor) => {
        let empty = new baseCtor();
        Object.keys(empty).forEach((name) => {
            Object.defineProperty(
                derivedCtor.prototype,
                name,
                Object.getOwnPropertyDescriptor(empty, name) ||
                Object.create(null)
            );
        });
    });
}

让我们测试调用
applyMixins()
,以确保我们了解
{new():object}
的功能和不匹配之处:

class Works {
    x = 1;
    constructor() { }
}
applyMixins(Works, []); // okay
可以工作
很好,因为它是一个不带参数的类构造函数

class CtorRequiresArg {
    y: string;
    constructor(y: string) { this.y = y; }
}

applyMixins(CtorRequiresArg, []); // error!
// -------> ~~~~~~~~~~~~~~~
// Type 'new (y: string) => CtorRequiresArg' 
// is not assignable to type 'new () => object'
CtorRequiresArg
失败,因为在构造字符串时必须传递一个
string
参数,如
new-CtorRequiresArg(“hello”)
。。。但是
applyMixins()
只接受可以在没有任何参数的情况下调用的构造函数

最后:

function NotACtor() { }

applyMixins(NotACtor, []); // error!
// -------> ~~~~~~~~
// Type '() => void' provides no match 
// for the signature 'new (): object'
NotACtor
失败,因为它被认为是不可构造的。这可能会令人惊讶,因为在运行时,没有任何东西会阻止您调用
new notator()
,但编译器认为,如果您想要一个类构造函数,您应该在
.ts
文件中使用
class
表示法。。。即使是针对ES5运行时,因为TypeScript也会自动降低它的级别。(有关更多信息,请参阅)



函数
是不可构造的,而比如说,
new()=>object
{new():object}
是可构造的。对您的用例有效吗?如果是这样的话,我会在有机会的时候写一个答案。如果没有,请在问题文本中用相关示例详细说明。祝你好运谢谢,我添加了
declare-type=new()=>object,然后使用
类型
而不是
函数
。但是与
{new():object}
相比有什么区别?是否存在一个类型声明来捕获任何可构造性,而不仅仅是具有特定签名的可构造性?我尝试了
new(…args:unknown[])=>object,但这不允许构造函数具有特定类型的参数。使用
new(…args:any[])=>对象编译器不再抱怨了,但是我们使用的引用
any
违背了我问题的目的。