8000 Unable to infer generic for a Pick / indexed-access type from a union of compatible types · Issue #16756 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Unable to infer generic for a Pick / indexed-access type from a union of compatible types #16756
Closed
@fongandrew

Description

@fongandrew

TypeScript Version: 2.3.4
Code

interface Test {
  cat: number;
  dog: number;
}

declare function doTest<T extends keyof Test>(x: Pick<Test, T>): void;

declare var cat: { cat: number };
doTest(cat);

declare var dog: { dog: number };
doTest(dog);

declare var catOrDog: { cat: number } | { dog: number };
doTest(catOrDog); // Error

Expected behavior: Last line should not error

Actual behavior: Property 'dog' is missing in type '{ cat: number; }'.

I understand this might be working as intended insofar that, in the last invocation of doTest, it's unclear what generic T to infer for the function. If T is 'cat'|'dog', then Pick<Test, 'cat'|'dog'> would require both cat and dog, which the union type for catOrDog does not match.

On the other hand, it seems very odd for a function to accept both an argument of type { cat: number } and type { dog: number } but not type { cat: number }|{ dog: number }.

As a work-around, it is possible to type doTest with additional generics, like so:

declare function doTest<T extends keyof CatAndDog, V extends keyof CatAndDog>(
  x: Pick<CatAndDog
5355
, T>|Pick<CatAndDog, V>
): void;
doTest<"cat", "dog">(catOrDog); // No eror

But this feels like a less than ideal solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0