Skip to content

Intersection of object and array breaks homomorphism #61745

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
1 task done
juhort opened this issue May 21, 2025 · 3 comments
Open
1 task done

Intersection of object and array breaks homomorphism #61745

juhort opened this issue May 21, 2025 · 3 comments

Comments

@juhort
Copy link

juhort commented May 21, 2025

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

Let's consider this Prettify type:

type Prettify<T extends object> = T extends Function
  ? T
  : { [P in keyof T]: T[P] };

There are two key things to note:

  1. T has a constraint of object.
  2. The mapped type { [P in keyof T]: T[P] } is homomorphic, so it should preserve the array structure in case of instantiations with arrays. So, for example, Prettify<[string, string]> returns [string, string].

Now, let's consider this instantiation of Prettify:

// Here, `T` is not constrained with `object`, so we take intersection with `object`
type Test<T> = Prettify<T & object>;

type T1 = Test<[string, string]>;
//   ^? type T1 = { [x: number]: string; 0: string; 1: string; length: 2; toString: () => string; toLocaleSt…

I'd expect T1 to be [string, string] but instead the array structure is lost.

Looks like this happens because of the object intersection:

type T1 = Prettify<[string, string] & object>;
//   ^? type T1 = { [x: number]: string; 0: string; 1: string; length: 2; toString: () => string; toLocaleSt…

The example above might be a bit contrived, but this is a common use case—we have object constraints at certain places and to satisfy those constraints we often have to take intersections with object.

Playground

@Andarist
Copy link
Contributor

Andarist commented May 21, 2025

I believe this is strongly related to #55386 (comment) . As we can see in #57801 intersections like this can (today) only produce arrays/tuples if they contain only array/tuple types. Mixing with other kinds of types doesn't work.

@juhort
Copy link
Author

juhort commented May 22, 2025

@Andarist So, it's a bug, right?

@Andarist
Copy link
Contributor

I wouldn't call it a bug per se. It's just how it works - there is an open question as to if the behavior should/could be changed. I think it would probably make sense to split the contained types into tuple/array types and non-tuple/array, map those separately and intersect the results. But that's not up to me to decide

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy