假设我有:
class A {
f():void{}
g():void{}
}
const a = new A();
type AFunctions = "f" | "g";
我想迭代 AFunctions 并生成新函数。 类似于映射类型,但有实现,当然不需要手动编写所有键。
伪代码
const b: A = {
for F in AFunctions add function F() {
return a[f]();
}
}
最佳答案
您可以使用 Object.getOwnPropertyNames
迭代类的属性和 Object.getPrototypeOf
.
function mapFunctions<T>(type: new (... params: any[])=> T) : { [P in keyof T] : ()=> void } {
let mapped: { [name: string] : ()=> void } = {}
let p = type.prototype;
while(p != Object.prototype) {
for (const prop of Object.getOwnPropertyNames(p)) {
if(prop == 'constructor') continue;
if(typeof p[prop] !== 'function') continue;
mapped[prop] = ()=> {
console.log(prop);
}
}
p = Object.getPrototypeOf(p);
}
return <any>mapped;
}
class A {
f(): void { }
g(): void { }
}
class B extends A{
h(): void { }
i(): void { }
}
let ss = mapFunctions(B); // has functions f,g,h,i
将函数类型与原始对象上的函数结果联系起来更加困难,Conditional types及其相关的 inference behavior在 2.8 中,您可以深入了解返回类型和参数类型,但现在您只能使用完整的函数类型,例如 { [P in keyof T] : ()=> T[P] }
(对于没有参数的函数,返回一个与原始函数具有相同签名的函数)或 { [P in keyof T] : (fn: T[P])=> void }
(对于以与原始具有相同签名的函数作为参数的函数)
关于TypeScript 迭代字符串联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48645337/