question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No constituent of type 'Function | (T & Function)' is callable.

See original GitHub issue

Bug Report

🔎 Search Terms

generic function union-type call-signatures

🕗 Version & Regression Information

  • This is a crash
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Generics
  • I was unable to test this on prior versions because _______

⏯ Playground Link

Playground link with relevant code

💻 Code

type Test = <T>(fn: T | Function) => void;
const test: Test = (fn) => {
  return typeof fn === 'function' ? fn() : null;
};
// This expression is not callable.
// No constituent of type 'Function | (T & Function)' is callable.

🙁 Actual behavior

Compiler throw error: This expression is not callable. Not all constituents of type ‘Function | (T & Function)’ are callable.

🙂 Expected behavior

Compile success

because both ‘Function | (T & Function)’ are callable.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
andrewbranchcommented, Oct 7, 2021

This changed between versions 4.3.5 and Nightly

It didn’t—it’s always been this way.

I think the behavior is correct but the error message is (very) wrong. What it means to say, I think, is that T might be a function, and if it is, you have no idea what its signature looks like, so calling it with zero arguments is not allowed. If you give T some constraint that implies it’s not a function, like T extends object or T extends string, it becomes callable after narrowing. But to say that “no constituent is callable” is certainly wrong.

0reactions
yellowsinkcommented, Apr 8, 2022

I should note that while it is true that technically, should T be a function, it would be impossible to safely call it, this issue is actually quite easy to hit in a situation where logically it should not be, using typeof:

function test<T>(val: Exclude<T, Function> | (() => T)) {
  // val can clealy either not be a function, or be a function that returns a T.

  if (typeof val === "function") {
    // typescript chooses to refine to quite the intriguing type:
    // (Exclude<T, Function> & Function) | (() => T)
    val(); // ERROR: Type 'Exclude<T, Function> & Function' has no call signatures
  }
}

val in this situation should not be callable since it excludes Function, yet it still makes it through.

Not sure if this is worthy of a separate issue or not, but its at least somewhat relevant here since Exclude<T, Function> & Function alone is callable.

EDIT: Another note, you may have more luck using instanceof Function if you want to never treat T as possibly being a function, even if it is one. That fixes the issue in my use case, but won’t in every.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Not all constituents of type 'X | Y' are callable (TS) | bobbyhadz
The error "This expression is not callable. Not all constituents of type 'X | Y" are callable" occurs when a value might be...
Read more >
Typescript interface: Not all constituents of type 'string ...
Typescript interface: Not all constituents of type 'string | (() => string)' are callable. Type 'string' has no call signatures · Ask Question....
Read more >
T | (() => T) · Issue #37663 · microsoft/TypeScript - GitHub
Actual behavior: This expression is not callable. Not all constituents of type '(() => T) | (T & Function)' are callable.
Read more >
Typescript: Not all constituents of type 'boolean - Paul Edenburg
This expression is not callable. Not all constituents of type 'boolean | (() => void)' are callable. Type 'false' has no call signatures....
Read more >
typescript this expression is not callable - You.com
To solve the "This expression is not callable. Type 'X' has no call signatures" TypeScript error: Make sure the value you are calling...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found