首页 > 解决方案 > Typescript:通过索引对类函数进行类型化访问

问题描述

我需要根据ExampleOne类的字段名称调用类的函数,DataValues从那里获取值并将它们传递给类实例的ExampleOne函数

告诉我如何通过索引器正确编写函数调用,如您所见,类型存在一些问题

class ExampleOne {
    f1(argStr: string): string {
        return `some text ${argStr}`;
    }
    f2(argNumber: number): string {
        return  `some text ${argNumber}`;
    }
}

class DataValues {
    f1: number = 64;
    f2: string = 'Hello';
}

function example() {
    const testClass = new ExampleOne();
    const data = new DataValues();

    for (const [key, value] of Object.entries(data)) {
        const functionName = key as keyof ExampleOne;
        const func = testClass[functionName];

        const arg: number | string = value;


        const result = func.apply(testClass, [arg]); 
/*                       | <---------- error this*
                         |
                         |
The 'this' context of type 
'((argStr: string) => string) | ((argNumber: number) => string)' 
is not assignable to method's 'this' of type 
'(this: ExampleOne, argStr: string) => string'.
Type '(argNumber: number) => string' is not assignable to type 
'(this: ExampleOne, argStr: string) => string'.
Types of parameters 'argNumber' and 'argStr' are incompatible.
Type 'string' is not assignable to type 'number'.(2684) */

    console.log(result);
    }
}

example();

游乐场链接

最初我试图这样做,但没有奏效:

    for (const [key, value] of Object.entries(data)) {
        const functionName = key as keyof ExampleOne;
        const func = testClass[functionName];

        const arg: number | string = value;

        const result = testClass[functionName](arg);
/*                                              | <--- error this
                                                |
                                                |
Argument of type 'string | number' is not assignable to parameter of type 'never'.
  Type 'string' is not assignable to type 'never'.(2345)
*/

    console.log(result);
    }

标签: typescript

解决方案


type FunctionCollection<V> = {
    [K in keyof V]: (_: V[K]) => string;
}

function applyFunctions<V>(fc: FunctionCollection<V>, dv: V): void {
    for (let key in dv) {
        console.log(fc[key](dv[key]));
    }
}

  /////////////
 // Example //
/////////////

class Values {
    f1: string = 'Hello';
    f2: number = 64;
}

class Functions {
    f1(argStr: string): string {
        return `some text ${argStr}`;
    }
    f2(argNumber: number): string {
        return  `some text ${argNumber}`;
    }
}

function example() {
    applyFunctions<Values>(new Functions(), new Values());
}

操场


推荐阅读