Suggest an editImprove this articleRefine the answer for “How do you extract a function's argument types with infer?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The argument types of a function can be extracted with a conditional type using `infer`, for example `type Args<T> = T extends (...args: infer A) => any ? A : never`. **Key point:** `infer` "pulls out" the arguments as a tuple, and if `T` is not a function, the result is `never`.Shown above the full answer for quick recall.Answer (EN)ImageTypeScript lets you **extract a function's argument types** using the `infer` keyword inside **conditional types**. This is one of the most common and useful use cases for `infer`. --- ## The general idea We check that some type `T` is **a function**, and we tell TypeScript: > "If `T` is a function whose arguments have type `A`, infer that `A`." --- ## Example 1: Extract the type of *one argument* ```javascript type FirstArg<T> = T extends (arg: infer A) => any ? A : never; type Example = (x: number) => void; type Result = FirstArg<Example>; // number ``` Here: - `T extends (arg: infer A) => any` checks whether `T` is a function. - `infer A` is how TypeScript "pulls out" the type of the first argument. - If `T` is not a function, the result is `never`. --- ## Example 2: Extract **all of a function's arguments** as a tuple ```javascript type Args<T> = T extends (...args: infer A) => any ? A : never; type Fn = (x: number, y: string) => boolean; type Params = Args<Fn>; // [number, string] ``` In this case `infer A` becomes a **tuple of argument types**. --- ## Example 3: Extract **the return type** ```javascript type Return<T> = T extends (...args: any[]) => infer R ? R : never; type Fn = (x: number, y: string) => boolean; type R = Return<Fn>; // boolean ``` > This is the implementation behind the built-in `ReturnType<T>`. --- ## Example 4: Get both the arguments and the result ```javascript type FunctionParts<T> = T extends (...args: infer A) => infer R ? { args: A; return: R } : never; type Fn = (id: string, active: boolean) => number; type Parts = FunctionParts<Fn>; /* { args: [string, boolean]; return: number; } */ ``` --- ## Example 5: The first argument ```javascript type FirstArg<T> = T extends (...args: [infer First, ...any[]]) => any ? First : never; type Fn = (name: string, age: number) => void; type A = FirstArg<Fn>; // string ``` > This uses tuple destructuring: `[infer First, ...any[]]`. --- ## Example 6: The last argument ```javascript type LastArg<T> = T extends (...args: [...any[], infer Last]) => any ? Last : never; type Fn = (a: number, b: string, c: boolean) => void; type L = LastArg<Fn>; // boolean ``` --- ## Example 7: The argument types of a class method ```javascript class User { save(id: number, active: boolean) {} } type MethodArgs = Args<User["save"]>; // [number, boolean] ``` > Works for any method - just take the type by key `["methodName"]` and apply the utility. --- ## Example 8: Implementing an analog of the built-in `Parameters<T>` TypeScript already has a ready-made utility type: ```javascript type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer A) => any ? A : never; type Fn = (x: number, y: string) => boolean; type Params = MyParameters<Fn>; // [number, string] ``` This is the equivalent of the standard `Parameters<Fn>`. --- ## Example 9: Getting the argument type of a callback function ```javascript type Callback = (err: Error | null, data: string) => void; type CallbackArgs = Args<Callback>; // [Error | null, string] ``` > Often used when typing APIs, Node.js callbacks, React hooks, and so on. --- ## Example 10: Applying the arguments to another function ```javascript type Args<T> = T extends (...args: infer A) => any ? A : never; function call<T extends (...args: any[]) => any>(fn: T, ...args: Args<T>) { return fn(...args); } function greet(name: string, age: number) { return `${name}, ${age}`; } call(greet, "Tim", 25); // ok call(greet, 25, "Tim"); // type error ``` Here `Args<T>` guarantees the correct order and types of the arguments. --- ## Summary | What we extract | Example | Result | |---|---|---| | One argument | `T extends (a: infer A) => any` | the type of the first argument | | All arguments | `T extends (...args: infer A) => any` | a tuple of arguments | | Return value | `T extends (...args: any[]) => infer R` | the result type | | First argument | `T extends (...args: [infer F, ...any[]]) => any` | the first argument | | Last argument | `T extends (...args: [...any[], infer L]) => any` | the last argument |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.