如何将类注释为工厂函数转换器 [英] How to annotate a class to factory function converter

查看:48
本文介绍了如何将类注释为工厂函数转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试注释一个采用类并返回工厂函数的函数,该函数返回该类的实例.(基本上,它消除了对 new 的需求).

I'm trying to annotate a function which takes a class and returns a factory function that returns instances of that class. (Basically, it removes the need to new).

这是我想出的:

const noNew = <T, U = new (...a: any[]) => T>(clazz: U): { (...b: any[]): T } => {
    return (...args: any[]) => {
        return new clazz(...args);
    };
}

由于至少两个原因,此方法不起作用:

This doesn't work for at least two reasons:

  1. 我得到一个不能对类型缺少调用或构造签名的表达式使用'new'."错误返回新的clazz(... args); .
  2. 我没有获得构造函数参数参数的任何类型完成或类型检查.

我该如何重写它而不会产生错误,并使参数具有类型识别能力?

How would I rewrite this not produce errors and to have the parameters type-aware?

推荐答案

第一个问题很容易解决,您实际上不需要 U ,只需使用 clazz:new(... a:any [])=>T

The first problem is simple to fix, you don't actually need U you can just use clazz: new (...a: any[]) => T

第二个问题要复杂一些,并且没有完美的解决方案.要获取参数类型,您将需要定义具有多个签名的函数,每个签名对应于构造函数参数列表的每个长度:

The second problem is a bit more complex, and there isn't a perfect solution. To get the parameter types, you will need to define function with multiple signatures, one for each length of the constructor parameter list:

function noNew<T>(clazz: new () => T): { (): T } 
function noNew<T, T1>(clazz: new (arg1: T1) => T): { (arg1: T1): T } 
function noNew<T, T1, T2>(clazz: new (arg1: T1, arg2: T2) => T): { (arg1: T1, arg2: T2): T } 
function noNew<T, T1, T2, T3>(clazz: new (arg1: T1, arg2: T2, arg3: T3) => T): { (arg1: T1, arg2: T2, arg3: T3): T } 
function noNew<T>(clazz: new (...a: any[]) => T): { (...b: any[]): T } {
    return (...args: any[]) => {
        return new clazz(...args);
    };
}

用法:

class AA {
    constructor (){}
}

class BB {
    constructor (a: string){}
}

let d = noNew(AA)();
let b = noNew(BB)("");

除具有可选参数的情况外,此方法均有效,然后 noNew 返回一个仅保留必需参数并删除可选参数的函数.

It works except for the case when you have optional parameters, then noNew returns a function that only keeps the required parameters and removes the optional ones.

class BB {
    constructor (a?: string){}
}
let b = noNew(BB)(); // No arguments

这篇关于如何将类注释为工厂函数转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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