TypeScript asserts that the Function is not callable

There seems to be an issue with TypeScript not recognizing that a function of type Function is not callable.

type Constructable = { new(...args: any[]): any }

function isClass(func: any) {
  return (
    typeof func === 'function' &&
    /^class\s/.test(Function.prototype.toString.call(func))
  )
}

function coerceOne(data: any, fn: Function | Constructable) {
  if (isClass(fn)) {
    const constructor = fn as Constructable
    return new constructor(data)
  } else {
    return fn(data) // <-- ERROR
  }
}

Error:

This expression is not callable.
  No constituent of type 'Function | Constructable' is callable.(2349)

https://www.typescriptlang.org/play?ssl=14&ssc=11&pln=14&pc=6#code/C4TwDgpgBAwg9gOwM7AE4FcDGwCGAjAG2gF4oBvKBCAdwAoA6RnVAcyQC4ocEQBtAXQCUnbiCgBfAFCSAZugTYAloiiKkMAjiRJachSJ6DykqFFQRg6VAii0TpqKEhwZUPZijEvUAOTvgygg+UABkIfamAPQAepia2gA6SJH0wBAotABi8kqI9GCocMBF4BCpcADKaIoILPSYOAQEujmCgvbtUrI5ASqYcBComBAA8lS0ACY4uAYgADRuCJzZCr02AD6wiCgY2PhERmT2iq60ahpaOjIIbcYOUP3IwA-baFjFqJ6LXEhbT7u4QgQCJmCxWGxUagvf7vOCoSbTHDtUziKAQAhIaBHe7mSzWRYI3DIiSSKRAA

Any suggestions on how to troubleshoot this problem?

Answer №1

Your custom type guard isClass requires a return type predicate: : func is Constructable

type Constructable = { new(...args: any[]): any }

function isClass(func: any): func is Constructable {
  return (
    typeof func === 'function' &&
    /^class\s/.test(Function.prototype.toString.call(func))
  )
}

function coerceOne(data: any, fn: Function | Constructable) {
  if (isClass(fn)) {
    const constructor = fn as Constructable
    return new constructor(data)
  } else {
    return fn(data)
  }
}

console.log(coerceOne('works', console.log))

Click here for more details

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a Lint No Nested Ternary Error while utilizing the ternary operator

Is there a way to prevent the occurrence of the "no nested ternary" error in TypeScript? disablePortal options={ // eslint-disable-next-line no-nested-ternary units=== "mm&quo ...

Organize elements within an array using TypeScript

I have an array that may contain multiple elements: "coachID" : [ "choice1", "choice2" ] If the user selects choice2, I want to rearrange the array like this: "coachID" : [ "choice2", "choice1" ] Similarly, if there are more tha ...

The arrow function in Jest is missing a name property

Currently, my setup includes: node.js: 9.8.0 Jest: 23.4.2 ts-jest: 23.1.3 typescript: 2.9.2 While attempting the following in my *.test.ts files: const foo = () => 'bar'; console.log(foo.name); // '' foo contains the name pro ...

React - retrieving the previous page's path after clicking the browser's "back" button

Imagine I'm on Page X(/path-x) and then navigate to page Y(/path-y). Later, when I click the "back" button in the browser. So my question is, how do I retrieve the value of /path-y in PageX.tsx? Note: I am utilizing react-router-dom ...

Unable to generate paths in Ionic 3

I am trying to view the actual route on the URL, but I'm having trouble figuring out exactly what needs to be changed. I've been referring to the documentation at: https://ionicframework.com/docs/api/navigation/IonicPage/ However, I keep encoun ...

What could be the reason for the Angular2 Component property not appearing on my webpage?

Here is the code snippet I am working with: import {Component} from "@angular/core"; @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <h2>{{secondTitle}}</h2> <main-page></ma ...

Is there a way to trigger an image flash by hovering over a button using the mouseover feature in AngularJS2?

When I hover over the 'click me' button, I want an image to appear on the webpage. When I stop hovering, the image should disappear using the mouseover option. This is what I attempted in my app.component.ts and my.component.ts files: Here is t ...

How to simulate a particular class from a node package using Jest mocks

In my project, I'm looking to specifically mock the Socket class from the net node module. The documentation for this can be found here. Within my codebase, there is a class structured similar to the following... import { Socket } from 'net&apo ...

Can all intervals set within NGZone be cleared?

Within my Angular2 component, I have a custom 3rd party JQuery plugin that is initialized in the OnInit event. Unfortunately, this 3rd party library uses setIntervals extensively. This poses a problem when navigating away from the view as the intervals rem ...

Typescript's spellbinding courses

I'm encountering some issues with Typescript and the "@botstan/Magic" library in nodejs. Before we proceed, please take a look at the "Magic" documentation. Follow these lines: import Magic from "@botstan/magic"; import * as _ from "lodash"; @ ...

Storing Buffer data in Postgres bytea using TypeORM is limited to only 10 bytes

I am encountering an issue while trying to store images in a postgres database, as only 10 bytes of data are being saved. Here is the sequence of events: Initially, I receive a base64 encoded string on my server. I then convert it into a Buffer, assign i ...

What are the drawbacks of removing comments from polyfills.ts in Angular CLI when using Internet Explorer?

Encountering a similar problem as described in Angular4 Application running issues in IE11. Although the suggested solution resolved the issue, I am left wondering why the lines referring to necessary polyfills for IE9, IE10, and IE11 were initially comm ...

generate a fresh array with matching keys

Here is an example array: subjectWithTopics = [ {subjectName:"maths", topicName : "topic1 of maths " }, {subjectName:"maths", topicName : "topic2 of maths " }, {subjectName:"English", topicName : &quo ...

Error: module not found in yarn

In my yarn workspace, I have organized folders named public and server. While working with TypeScript in VS Code, I encounter an error message stating: Cannot find module 'x' Interestingly, even though the error persists, IntelliSense suggests ...

Finding the location of a file within a published web component

I am currently working on a webcomponent where I need to include a link tag in the head section and set the href attribute to a folder within a node module. At this stage, during the development of my component, my project structure looks like this: http ...

Modify an array by incorporating values from another array that have a matching property

I have two arrays that look like this let array1 = [{ 'id': 1, 'name': 'A' }, { 'id': 2, 'name': 'B' }, { 'id': 3, 'name': ' ...

What is the recommended TypeScript type for setting React children?

My current layout is as follows: export default function Layout(children:any) { return ( <div className={`${styles.FixedBody} bg-gray-200`}> <main className={styles.FixedMain}> <LoginButton /> { children } ...

Using TypeScript with AWS Lambda: To package imports or not to package? Alternatively: Error in Runtime.ImportModule: Module '@aws-sdk/...' not found

I have been working with the code in my lambda.ts file, attempting to execute it on an AWS Lambda: import 'aws-sdk' import { /* bunch of stuff... */ } from "@aws-sdk/client-cloudwatch-logs"; import {Context, APIGatewayProxyResult} from ...

The type 'Bar<T>' cannot be assigned to type 'T extends number ? number | Bar<T> : Bar<T>'

I'm struggling with this particular code snippet: class Foo<T> { x?: T extends string ? string | Foo<T> : Foo<T> } function bar<T>(): Foo<T> { const x: Foo<T> = { } return { x } } Can anyone explain why the ...

Utilize the text box feature for manipulating the data field in Angular4

Within my grid view, there exists a column labeled remark. This specific field contains various values, one of which is absence. My objective is to modify the remark value exclusively when it is equal to absence, followed by clicking the corresponding icon ...