Acknowledgement
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:
T has a constraint of object.
- 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
Acknowledgement
Comment
Let's consider this
Prettifytype:There are two key things to note:
Thas a constraint ofobject.{ [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:I'd expect
T1to be[string, string]but instead the array structure is lost.Looks like this happens because of the
objectintersection:The example above might be a bit contrived, but this is a common use case—we have
objectconstraints at certain places and to satisfy those constraints we often have to take intersections withobject.Playground