Skip to content

Generic index into two types not seen as assignable, even if the two types are identical for all relevant keysΒ #58905

Closed as not planned
@jcalz

Description

@jcalz

πŸ”Ž Search Terms

generic, indexed access, supertype

πŸ•— Version & Regression Information

⏯ Playground Link

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions