我正在尝试注释一个接受类的函数,并返回一个返回该类实例的工厂函数。 (基本上,它不需要new
)。
以下是我提出的建议:
const noNew = <T, U = new (...a: any[]) => T>(clazz: U): { (...b: any[]): T } => {
return (...args: any[]) => {
return new clazz(...args);
};
}
这至少有两个原因:
return new clazz(...args);
错误。我如何重写这不会产生错误并使参数具有类型感知功能?
答案 0 :(得分:1)
第一个问题很容易修复,您实际上并不需要U
只能使用clazz: new (...a: any[]) => T
第二个问题有点复杂,并没有一个完美的解决方案。要获取参数类型,您需要定义具有多个签名的函数,每个签名对应于构造函数参数列表的每个长度:
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
返回一个只保留所需参数并删除可选参数的函数。
class BB {
constructor (a?: string){}
}
let b = noNew(BB)(); // No arguments