Is there any difference between these 2 mapped types?
type UppercaseProperties1<T> = {
[P in keyof T as Capitalize<string & P>]: T[P]
}
type UppercaseProperties2<T> = {
[P in keyof T as Capitalize<P & string>]: T[P]
}
I see that in the TypeScript playground a simple type like Person
interface Person {
name: string;
age: number;
}
gives the same result for each of these mapped types:
type UppercasePerson = {
Name: string;
Age: number;
}
But perhaps there are some cases where this nuance can make a difference?
P.S.
I asked AI bot and here is its answer (I’m still trying to make sense of it):
You’re right that for simple types like
Person
, both
UppercaseProperties1
andUppercaseProperties2
will produce the
same result.The difference between
string & P
andP & string
is subtle, but
it’s related to how TypeScript handles type intersections.When you write
P & string
, you’re creating an intersection type that
combines the properties ofP
with those ofstring
. However, since
P
is a key type (i.e., a subtype ofkeyof any
), it already has
some properties in common with string. By intersectingP
with
string
, you’re essentially adding more constraints toP
.On the other hand, when you write
string & P
, you’re creating an
intersection type that combines the properties ofstring
with those
ofP
. Since string is a more general type thankeyof any
, this
intersection effectively “overrides” some of the properties ofP
with those ofstring
.Now, here’s where it gets interesting: when you use
Capitalize
on an
intersection type, it will only work if the intersection type has a
single property that can be capitalized. If the intersection type has
multiple properties (e.g., becauseP
is a union type),Capitalize
won’t know which one to capitalize.In the case of
UppercaseProperties1
, usingstring & P
ensures that
the intersection type always has a single property, even ifP
is a
union type. This makes it safe to useCapitalize
.In contrast,
UppercaseProperties2
usesP & string
, which can
result in an intersection type with multiple properties ifP
is a
union type. In this case,Capitalize
might not work as expected.
3