Skip to content

Issues working with Generic Constraints #791

Closed
@Dsan10s

Description

@Dsan10s

Hello Typescript team!

I've been working on updating my team's typescript codebase from v 3.2.1 to v 3.6.4

I'm having some issues updating my codebase to support the breaking changes, and wanted to start a discussion to see if what I'm coming across is by design, and if so, what is the recommended solution for working through it.

Below I'll create a simplified example of the issue we're having, and I've verified that the issue only appears after and including Typescript 3.5. I believe the issue may be related to this:

interface StoreParams {
  key1: string;
  key2: number;
  key3: string[];
}

function get<Key extends keyof StoreParams>(key: Key): StoreParams[Key] | null {
  const key1Return: string = 'key1Return';
  const key2Return: number = 2;
  const key3Return: string[] = ['a', 'b', 'c'];

  if (key === 'key1') {
    return key1Return;
  }

  if (key === 'key2') {
    return key2Return;
  }

  if (key === 'key3') {
    return key3Return;
  }

  return null;
}

The above code results in an error in each of the key return statements, respectively they are:

Type 'string' is not assignable to type 'StoreParams[Key] | null'.
Type 'number' is not assignable to type 'StoreParams[Key] | null'.
Type 'string[]' is not assignable to type 'StoreParams[Key]'.
  Type 'string[]' is not assignable to type 'never'.

It seems in each of the return statements, the return type is still StoreParams[Key] | null, where Key has not been filtered down after the if statement which normally acts as a type guard for key.

If I replace the generic Key with just keyof StoreParams, the type guards seem to work on key, but I've lost the benefit of the generic in that I'm still just returning StoreParams[keyof StoreParams], meaning in each of the return statements I can return string | number | string[] | null.

Any help or advice would be greatly appreciated, and huge shoutout to the team for this immensely useful tool!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions