Skip to content

Function argument type inference in recursively modified types #50468

Closed

Description

@Azarattum

Bug Report

Whenever we use a recursive generic to alter an array of functions, then use this type as a function's arguments, parameter arrow functions do not have their arguments inferred by TypeScript.

I've been trying to get this properly working to implement a pipe typings (related #30370, #25660). Which lead me to investigate why the arguments in the suggested solution are not inferred. I nailed this down to recursion type modification and made a minimal reproduction (see the code below).

If this is solved the mentioned above issues would also resolve (and probably more).

🔎 Search Terms

recursion, flow, pipe, chain, inference

🕗 Version & Regression Information

  • The issue is present since version 4.1.5 (playground) when circular references were introduced that made possible to implement recursions. And still preset until 4.8.0-beta (playground).

💻 Code

Playground link with relevant code

/** Recursively replaces all items in array T with U */
type RecursiveReplace<T, U> =
    T extends [any, ...infer Tail]
    ? [U, ...RecursiveReplace<Tail, U>]
    : T;

/** Example of recursive replacement */
type Example = RecursiveReplace<[1,2,3], 3>
//   ^? type Example = [3, 3, 3]

/** This should transform any function signatures passed to it to `(_: number) => void` */
function test<T extends any[]>(..._: RecursiveReplace<T, (_: number) => void>) {}

/** This works fine */
test(
    (_: number) => {}
)

/** TypeScript complains about the wrong signature. This is OK too */
test(
    (_: string) => {} // ERROR: Type 'number' is not assignable to type 'string'
)

/** ------------------------------------------ ↓ THE BUG ↓ ------------------------------------------- */ 
/** TypeScript complains about an implicit `any`. However the argument should be inferred as `number`! */
test(
    (_) => {},
//   ^? (parameter) _: any
);
/** -------------------------------------------------------------------------------------------------- */

🙁 Actual behavior

Recursive modification of type signatures breaks argument inference in functions.

🙂 Expected behavior

Function parameters should be properly inferred even after type signature was recursively modified.

Activity

  1. RyanCavanaugh commented on Aug 26, 2022

    @RyanCavanaugh
    Member

    If you make the example need generics in the first place, it quickly becomes apparent that you need an unbounded number of inference rounds to type these things properly -- see #30134

  2. typescript-bot commented on Aug 28, 2022

    @typescript-bot
    Contributor

    This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  3. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions