microsoft / microsoft/TypeScript

Narrowed generic type is ignored in return type of callback passed to generic function

Open
#54,405 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Domain: check: Type Inference Help Wanted
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

Bug Report

See the code below. When returning a value with a narrowed generic type, the callback can't be assigned to a parameter whose return type is the same as the narrowed type. The error only happens when the callback is passed to a generic function (even when the generic isn't used for anything).

🔎 Search Terms

generic narrow callback return type

🕗 Version & Regression Information

I tried a bunch of versions in the playground, they all have the bug

⏯ Playground Link

Playground link with relevant code

💻 Code
type Union = number | string;
type Root = Record<string, Union>;

function noBug(cb: () => number) {}
function bug<T>(cb: () => number) {}

function foo<T extends Root>(root: T, key: keyof T) {
  const union = root[key];
  //    ^?

  noBug(() => {
    //     ^?
    if (typeof union === "string") throw new Error();
    return union;
    //     ^?
  });
  bug(() => {
    //   ^?
    if (typeof union === "string") throw new Error();
    return union;
    //     ^?
  });
}
🙁 Actual behavior

The call to bug results in this error: Argument of type '() => T[keyof T]' is not assignable to parameter of type '() => number'.

🙂 Expected behavior

The call to bug should have no errors, like the call to noBug.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked TypeScript Playground reproduction and compare callback return-type checking in the non-generic noBug function with the generic bug function. Trace the generic callback checking path and verify that the narrowed value is accepted as number in bug; preserve coverage for this example.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.