#Why does intersection of two objects give value of undefined?

13 messages · Page 1 of 1 (latest)

wide pike
#
type Merge<T1 extends {}, T2 extends T1> = {
 [Key in keyof T1]: (T1 & T2)[Key]
}
type S1 = { name?: string };
type S2 = { name: string };
type S3 = Merge<S1, S2>['name']
//   ^ why is this string | undefined?
// but the following is not:
type S4 = (S1 & S2)['name'] // string
jaunty oyster
#

Making a key optional means that its value can be undefined but the opposite is not true

#

The "flag" that a key is optional or not is specified on the key and you're mapping T1

wide pike
#

So you're saying { name?: string } is not equivalent to {name: string | undefined}?

jaunty oyster
#

No

glass kernelBOT
#
RogerC#3099

Preview:```ts
type Foo = {
bar: number
baz: boolean | undefined
}

const w: Foo = {
bar: 10,
}

type Bar = {
bar: number
baz?: boolean // It is boolean | undefined
}

const w2: Bar = {
bar: 10,
}```

jaunty oyster
#

You can enable the exactOptionalPropertyTypes option to change the behaviour a little

wide pike
#

hmm I think I understand the issue. The name key in S1 says that whatever the value type is, it can be undefined as well. Sort of like an implicit undefined. So even though the value type is (string | undefined) & string I'll still get undefined because of the key. Right?

jaunty oyster
#

{ foo: string | undefined } means that the key 'foo' must exist but that its value can be undefined. { foo? : string } means that the key 'foo' is optional so its type is string but also implicitly undefined. That is, unless exactOptionalPropertyTypes is enabled.

wide pike
#

Ah gotcha, that distinction makes sense. So I think the way to go about doing what I need is to do

{ [Key in (T1 & T2): (T1 & T2)[Key] }

which would make it simply equivalent to just T1 & T2

jaunty oyster
#

I don't know what you're actually trying to do 😦

wide pike
#

Ah sorry, I was trying to figure out how to implement the Merge type and. The desired behaviour being that if a key in t2 can not be undefined, the output type should not be undefined as well

#

!solved