You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
interfaceFoo{a: string,b: number}interfaceBarextendsFoo{c: boolean}functionbar<KextendskeyofBar>(k: K,v: Bar[K]){}functionfoo<KextendskeyofFoo>(k: K,v: Foo[K]){bar(k,v)// error!// ~// Argument of type 'Foo[K]' is not assignable to parameter of type 'Bar[K]'.// Property 'c' is missing in type 'Foo' but required in type 'Bar'.(2345)}
π Actual behavior
bar(k, v) fails because Foo[K] is supposedly not assignable to Bar[K].
π Expected behavior
bar(k, v) should succeed because Foo[K] is identical to Bar[K]; the only difference between Foo and Bar occurs in a key that K can never be.
Additional information about the issue
This is presumably a design limitation introduced with #30769. And while it's similar to #32693, it's different enough that I'd like to see an official word about it. If there is an existing issue that's the same as this, I didn't find it. Can anyone find one this duplicates? I'm investigating a SO question and while I feel certain I've seen this before, I keep hitting things like #32693 which aren't about generics at all.
On the face of it, if Pick<Foo, KC> and Pick<Bar, KC> are identical, then for generic K extends KC, Foo[K] and Bar[K] should also be identical. Yes, if K turns out to be a union, then you run into the soundness issue that #30769 fixed. We already allow T[K] to be assignable to T[K] if K is generic, so it's not really soundness that's at play here.... we've already decided that generic keys are a way of sidestepping this (I'm looking at you, #47109). I'm guessing it's just not worth the performance hit to check assignability of parts of the source and target object types, so it's a design limitation? Maybe?
The text was updated successfully, but these errors were encountered:
the only difference between Foo and Bar occurs in a key that K can never be.
How does one arrive at this conclusion except via exhaustive analysis of possible values of K? Note that from TS's perspective, this example isn't any different from one with
Right, so it's presumably not worth the performance hit to look at K extends keyof Bar and compare Pick<Foo, keyof Bar> to Pick<Bar, keyof Bar> instead of comparing Foo to Bar. Synthesizing the Pick types for every generic assignment would be equivalent to such "exhaustive analysis", I presume?
π Search Terms
generic, indexed access, supertype
π Version & Regression Information
β― Playground Link
Playground link
π» Code
π Actual behavior
bar(k, v)
fails becauseFoo[K]
is supposedly not assignable toBar[K]
.π Expected behavior
bar(k, v)
should succeed becauseFoo[K]
is identical toBar[K]
; the only difference betweenFoo
andBar
occurs in a key thatK
can never be.Additional information about the issue
This is presumably a design limitation introduced with #30769. And while it's similar to #32693, it's different enough that I'd like to see an official word about it. If there is an existing issue that's the same as this, I didn't find it. Can anyone find one this duplicates? I'm investigating a SO question and while I feel certain I've seen this before, I keep hitting things like #32693 which aren't about generics at all.
On the face of it, if
Pick<Foo, KC>
andPick<Bar, KC>
are identical, then for genericK extends KC
,Foo[K]
andBar[K]
should also be identical. Yes, ifK
turns out to be a union, then you run into the soundness issue that #30769 fixed. We already allowT[K]
to be assignable toT[K]
ifK
is generic, so it's not really soundness that's at play here.... we've already decided that generic keys are a way of sidestepping this (I'm looking at you, #47109). I'm guessing it's just not worth the performance hit to check assignability of parts of the source and target object types, so it's a design limitation? Maybe?The text was updated successfully, but these errors were encountered: