简体   繁体   中英

Infer Parameter Type of a Function

I would like to infer the type of a parameter in Typescript but was not lucky until yet.

I have the following Code

// 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);

Is it somehow possible to infer the type for payload in the Dispatch<T> type? I played around with the Parameters stuff which was added in 2.8 but still have no clue how to solve it.

The key on the other hand works just fine. So since i have the Base Type T and the key i thought it should be possible to find out the type of the parameter.

Dispatch would have to be a generic function (not just a generic type) to be able to capture the actual type of the argument passed in and use this to get the corect parameters from T

// 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);

Note: solution is Typescript 3.0 and above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM