Skip to content

Source provides no match for required element at position 0 in target despite source extending [any, ...any[]]Β #48401

Description

@Roaders

Bug Report

πŸ”Ž Search Terms

tuple, conditional type

πŸ•— Version & Regression Information

4.6.2

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Conditional Types

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type RecursiveType<TList extends [any, ...any[]]> = ((
    ...list: TList
) => unknown) extends (h: infer Head, ...tail: infer Tail) => unknown
    ? ((h: Head) => unknown) extends (h: Array<infer R>) => unknown
        ? R
        : ((h: Head, ...tail: Tail) => unknown) extends (
              h: any,
              ...tail: [any, ...any[]] // ensure that Tail extends [any, ...any[]]
          ) => unknown
        ? RecursiveType<Tail> // Error: Source provides no match for required element at position 0 in target
        : unknown
    : unknown;

πŸ™ Actual behavior

Comile error:
Error: Source provides no match for required element at position 0 in target

πŸ™‚ Expected behavior

We should be able to pass Tail back into RecursiveType as we are ensuring that Tail extends [any, ...any[]]. I have tried this a few different ways, by re-inferring the type of the tail and by switching the Tail and [any, ...any[]] around so we check that [any, ...any[]] extends Tail instead.

Activity

  1. MartinJohns commented on Mar 24, 2022

    @MartinJohns
    Contributor

    Simple workaround: ...tail: [infer TH, ...infer TT] and RecursiveType<[TH, ...TT]>

  2. Roaders commented on Mar 24, 2022

    @Roaders
    Author

    yes, it does. Thanks very much for the workaround. It doesn't work when I specify the type of the items in the tuple though:

    type RecursiveType<TList extends [Item, ...Item[]]> = ((
        ...list: TList
    ) => unknown) extends (h: infer Head, ...tail: infer Tail) => unknown
        ? ((h: Head) => unknown) extends (h: Array<infer R>) => unknown
            ? R
            : ((h: Head, ...tail: [Item, ...Item[]]) => unknown) extends (
                  h: any,
                  ...tail: [infer TH, ...infer TT] // ensure that Tail extends [Item, ...Item[]]
              ) => unknown
            ? RecursiveType<[TH, ...TT]> // Error: Type 'TH' is not assignable to type 'Item'
            : unknown
        : unknown;

    Playground

  3. RyanCavanaugh commented on Mar 28, 2022

    @RyanCavanaugh
    Member

    We don't have a way to indirectly propagate the facts of the parent constraint into the infer result in a way that is still generic but allows it to directly pass constraint checks. #48112 should help with this use case

  4. Roaders commented on Mar 29, 2022

    @Roaders
    Author

    Yes, that would have definitely helped in several places. I look forward to it being merged. Thanks

  5. 50an6xy06r6n commented on Aug 4, 2023

    @50an6xy06r6n

    Is this why T[] is not assignable to [T, ...T[]] | []?

    That's a degenerate case, but I have some use for things like this:
    const f = <T,>(p: readonly [G<T>, ...G[]] | []) => {}

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

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions