Skip to content

typeof something === 'function' No longer narrow certain generic typed variable to Function #54522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thynson opened this issue Jun 5, 2023 · 3 comments · Fixed by #54845
Closed
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@thynson
Copy link

thynson commented Jun 5, 2023

Bug Report

typeof something === 'function' seems no longer narrow something to a Function in 5.1.3, when something has a generic type under certain circumstance.

🔎 Search Terms

typeof function

🕗 Version & Regression Information

The following code failed to compile on 5.1.3, while typescript prior to 5.0.4 works.
- This changed between versions 5.0.4 and 5.1.3

Updates:
The following code pass tsc before 4.7.4
fnLength1 is rejected by tsc since 4.8
methodFnLength is rejected by tsc since 5.1

⏯ Playground Link

Playground link

💻 Code

export function methodFnLength<T extends {}, K extends keyof T>(
  obj: T,
  methodKey: K,
): number {
  const fn = obj[methodKey];
  if (typeof fn !== 'function') {
    return 0;
  }
  return fn.length; // Since Typescript 5.1: fn has type T[K], instead of Function
}

export function fnLength1<T extends object>(
  fn: T
): number {
  if (typeof fn !== 'function') {
    return 0;
  }
  return fn.length; // Since Typescript 4.8: fn is narrowed to never
}

export function fnLength2<T>(
  fn: T
): number {
  if (typeof fn !== 'function') {
    return 0;
  }
  return fn.length; // okay
}

🙁 Actual behavior

It does not narrow fn to Function in all cases.

🙂 Expected behavior

It does narrow fn to Function in all cases as expected.

@thynson thynson changed the title typeof something === 'function' No longer narrow target variable to a Function typeof something === 'function' No longer narrow certain generic typed variable to Function Jun 5, 2023
thynson added a commit to sensejs/sensejs that referenced this issue Jun 6, 2023
@RyanCavanaugh
Copy link
Member

Posting for bisect

export function methodFnLength<T extends {}, K extends keyof T>(
  obj: T,
  methodKey: K,
): number {
  const fn = obj[methodKey];
  if (typeof fn !== 'function') {
    return 0;
  }
  return fn.length; // fn has type T[K], instead of Function
}

@typescript-bot
Copy link
Collaborator

The change between origin/release-5.0 and origin/release-5.1 occurred at 84a09c7.

@RyanCavanaugh
Copy link
Member

PR is #53059

@weswigham thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants