typescripttypescript-conditional-types

How to get argument types from function in Typescript


I may have missed something in the docs, but I can't find any way in typescript to get the types of the parameters in a function. That is, I've got a function

function test(a: string, b: number) {
    console.log(a);
    console.log(b)
}

I want access to the types string and number, likely as a tuple.

I know I can get the type of the function itself, as typeof test, or the return type via ReturnType<test>.

When I tried keyof typeof test, it returned never, which I also couldn't explain.

Other answers like this one point to extends, but I don't really understand how that works and don't give me an easy way to access the set-of-all-params as a type.


Solution

  • Typescript now comes with a predefined Parameters<F> type alias in the standard library, which is almost the same as ArgumentTypes<> below, so you can just use that instead of creating your own type alias.

    type TestParams = Parameters<(a: string, b: number) => void> // [string, number]
    

    Then to get for example the second parameter's type you can use the numeric indexing operator:

    type SecondParam = TestParams[1] // number
    

    Original answer:


    Yes, now that TypeScript 3.0 has introduced tuples in rest/spread positions, you can create a conditional type to do this:

    type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
    

    Let's see if it works:

    type TestArguments = ArgumentTypes<typeof test>; // [string, number]
    

    Looks good. Note that these beefed-up tuples also capture things like optional parameters and rest parameters:

    declare function optionalParams(a: string, b?: number, c?: boolean): void;
    type OptionalParamsArgs = ArgumentTypes<typeof optionalParams>; 
    // [string, (number | undefined)?, (boolean | undefined)?]
    
    declare function restParams(a: string, b: number, ...c: boolean[]): void;
    type RestParamsArgs = ArgumentTypes<typeof restParams>;
    // [string, number, ...boolean[]]