-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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?