Description
π Search Terms
generic, indexed access, supertype
π Version & Regression Information
- This changed between versions 3.3 and 3.5
- This changed in commit or PR Improve soundness of indexed access typesΒ #30769, probably
β― Playground Link
π» Code
interface Foo {
a: string,
b: number
}
interface Bar extends Foo {
c: boolean
}
function bar<K extends keyof Bar>(k: K, v: Bar[K]) { }
function foo<K extends keyof Foo>(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?