Skip to content

Function can return wrong values despite type #30603

Description

TypeScript Version: 3.4.0-dev.20190326

Search Terms: Function Generic Extends Keyof Property

Code

interface Type {
  a: 123;
  b: "some string";
}

function get123<K extends keyof Type>(): Type[K] {
  return 123;
}

Expected behavior:
The function get123 would yield an error as the return type might not be correct as it depends on K.

Actual behavior:
No error for get123. That function would obviously always return 123.

Playground Link: Example on TypeScript Playground

Activity

  1. jack-williams commented on Mar 27, 2019

    @jack-williams
    Collaborator

    I think this is an unsoundness that exists to support index access types on this. The assignability rules for Type[K] are defined as:

    // A type S is related to a type T[K], where T and K aren't both type variables, if S is related to C,
    // where C is the base constraint of T[K]
    

    The base constraint of Type[K] is the type you get when indexing into Type using the base constraint of K which is "a" | "b". So the checker sees that 123 is assignable to Type[K] as:

    • 123 is assignable to 123 | "some string"
    • and Type[K] ==> Type["a" | "b"] ==> 123 | "some string"

    The way to prevent the unsoundness would be to write it using two variables, though I'm not sure this actually solves your problem.

    function get123<K extends keyof Type, T extends Type = Type>(): T[K] {
      return 123;
    }

    EDIT: Just to add the caveat that I think this is what it's doing, and why, but nothing I say is official or guaranteed to be correct.

  2. jack-williams commented on Mar 27, 2019

    @jack-williams
    Collaborator

    See this comment by Anders for (much) more detail.

  3. DanielRosenwasser commented on Mar 27, 2019

    @DanielRosenwasser
    Member

    Feels bad - but does that mean we should mark this as a duplicate Anders Hejlsberg (@ahejlsberg)?

  4. jack-williams commented on Mar 27, 2019

    @jack-williams
    Collaborator

    Would it be too much to restrict the unsoundness to cases where the object type is generic, but the key type is concrete? This example would be the converse and use the sound path.

  5. ahejlsberg commented on Mar 27, 2019

    @ahejlsberg
    Member

    Jack Williams (@jack-williams) I'll give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixedFixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions