Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Roaders opened this issue Mar 24, 2022 · 5 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@Roaders
Copy link

Roaders commented Mar 24, 2022

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.

@MartinJohns
Copy link
Contributor

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

@Roaders
Copy link
Author

Roaders commented Mar 24, 2022

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

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Mar 28, 2022
@RyanCavanaugh
Copy link
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

@Roaders
Copy link
Author

Roaders commented Mar 29, 2022

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

@50an6xy06r6n
Copy link

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
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants