TypeScript迭代字符串联合类型

时间:2018-02-06 14:29:10

标签: typescript

假设我有:

class A {
 f():void{}
 g():void{}
}
const a = new A();

type AFunctions = "f" | "g";

我想迭代AFunction并产生新的功能。 与映射类型类似,但有实现,当然没有手动编写所有键。

伪代码

const b: A = {
 for F in AFunctions add function F() {
   return a[f]();
  }
}

1 个答案:

答案 0 :(得分:3)

您可以使用Object.getOwnPropertyNamesObject.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及其在2.8中的关联inference behavior将让您深入查看返回类型和参数类型,但是现在你只能使用完整的函数类型,例如{ [P in keyof T] : ()=> T[P] }(对于没有返回与原始函数具有相同签名的函数的参数的函数)或{ [P in keyof T] : (fn: T[P])=> void }(对于需要的函数)与原始签名相同的函数作为参数)