Skip to content

Error type on spreading array with additional props #59849

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

Open
ssalbdivad opened this issue Sep 4, 2024 · 1 comment Β· May be fixed by #59864
Open

Error type on spreading array with additional props #59849

ssalbdivad opened this issue Sep 4, 2024 · 1 comment Β· May be fixed by #59864
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@ssalbdivad
Copy link

πŸ”Ž Search Terms

array intersection spread any

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://tsplay.dev/wOdoMN

πŸ’» Code

type withExtraProps = extractArray<{ name: string } & string[]>;
//   ^? any[]

type extractArray<t extends readonly unknown[]> = [...{ [i in keyof t]: t[i] }];

πŸ™ Actual behavior

Inferred as any[] due to an internal error type

πŸ™‚ Expected behavior

Inferred as string[]

Additional information about the issue

@Andarist mentioned this could be related to #59260

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Sep 4, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Sep 4, 2024
@Andarist
Copy link
Contributor

Andarist commented Sep 5, 2024

The last improvements to homomorphic mapped typed instantiated with intersections containing arrays/tuples can be found in this PR: #57801

It even comes with a test case showing the (current) expected behavior for arrays intersected with non-array types (TS playground):

type Box<T> = { value: T };
type Boxify<T> = { [K in keyof T]: Box<T[K]> };
type T5 = Boxify<string[] & { x: string }>;

The result of this is an "expanded" object type. The problem, likely, is that when the result of that gets passed to a spread operator... it won't allow it because this is not an array/tuple type. So it returns an error type upon this instantiation.

However, just spreading arrays/tuples within intersections often "just works" (TS playground):

type Test1<T extends unknown[]> = [...T]

type Input1 = string[] & { a: number }
type Result1 = Test1<Input1>
//    ^? type Result1 = string[]

type Input2 = (string | number)[] & ['foo', string, 42]
type Result2 = Test1<Input2>
//    ^? type Result2 = (string | 42)[]

type Input3 = [string | boolean, string | symbol, ...number[]] & ['foo', string, 43]
type Result3 = Test1<Input3>
//    ^? type Result3 = (string | 43)[]

type Input4 = [string | boolean, boolean, ...number[]] & ['foo', string, 44]
type Result4 = Test1<Input4>
//    ^? type Result4 = any[]

It's worth noticing that Result4 displays as any[] - it's likely that this one is also an error type but I haven't verified it internally.

I'd argue that both should behave the same since the spread mapped type in the example is basically just an Identity type. We can imagine mapped types with other template types but I think it doesn't matter all that much. The output tuple/array structure can be resolved in situation like this and then the element types can be mapped with the template type.

So I think that isArrayOrTupleOrIntersection added in #57801 should be changed to use some over every and then the non-array/tuple members should be simply ignored. Alternatively, a logic like this could be applied within a "spread context" but making the instantiation logic contextual doesn't make much sense to me here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants