Skip to content

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

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions