推断函数的参数类型

时间:2019-05-11 08:50:33

标签: typescript

我想推断Typescript中的参数类型,但直到现在还不走运。

我有以下代码

// is it possible to find out the type of the payload parameter?
type Dispatch<T> = (prop: keyof T, payload?: any) => any; 

class TestClass<T> {
  obj: T;
  dispatch: Dispatch<T> = (prop, payload) => {
    const func = this.obj[prop];
    return (func as any)(payload);
  };

  constructor(obj: T) {
    this.obj = obj;
  }
}

interface SomeFuncs {
  foo(payload: string): string;
  bar(payload: number): string;
}

const someFuncs: SomeFuncs = {
  foo(payload) {
    return 'Hello ' + payload;
  },
  bar(payload) {
    const result = 10 + payload;
    return 'Your result is ' + result;
  },
};

const testClass = new TestClass(someFuncs);
const result = testClass.dispatch('bar', 'bla'); // I would like to get here an error because the payload for bar should be of type number
console.log(result);

是否可以通过某种方式推断出Dispatch<T>类型的有效载荷类型?我玩过2.8中添加的Parameters东西,但仍然不知道如何解决它。

另一方面,该键工作正常。因此,由于我拥有基本类型T和键,因此我认为应该可以找到参数的类型。

1 个答案:

答案 0 :(得分:2)

Dispatch必须是通用函数(而不仅仅是通用类型),才能捕获传入的参数的实际类型,并使用它从T中获取corect参数。 / p>

// is it possible to find out the type of the payload parameter
type Dispatch<T extends Record<keyof T, (...a: any[]) => any>> = <K extends keyof T>(prop: K, ...payload: Parameters<T[K]>) => any; 

class TestClass<T extends Record<keyof T, (...a: any[]) => any>> {
    obj: T;
    dispatch: Dispatch<T> = (prop, ...payload) => {
        const func = this.obj[prop];
        return func(...payload);
    };

    constructor(obj: T) {
        this.obj = obj;
    }
}

interface SomeFuncs {
    foo(payload: string): string;
    bar(payload: number): string;
}

const someFuncs: SomeFuncs = {
    foo(payload) {
        return 'Hello ' + payload;
    },
    bar(payload) {
        const result = 10 + payload;
        return 'Your result is ' + result;
    },
};

const testClass = new TestClass(someFuncs);
const result = testClass.dispatch('bar', 'bla'); // err
const result2 = testClass.dispatch('bar', 0); // ok
console.log(result);

注意:解决方案是Typescript 3.0及更高版本