What is the process of converting the new syntax of SomeFunction() to TypeScript?

When I try to convert a basic JS file to TS while having implicit "any" disabled, I encounter the following error:

Error TS7009: When attempting to create a new expression without a constructor signature, it implicitly defaults to an 'any' type.

interface Logger {
    new (): any;
}

interface LoggerInstance {
}

function Logger(): void {
}


var defaultLogger: LoggerInstance = new Logger();//error TS7009

I'm stuck on how to resolve this issue without turning the Logger function into a class.

The TypeScript compiler was providing suggestions for improvement when implicit any wasn't disabled, so I prefer to keep that setting enabled.

Update: After removing "new" from the Logger interface and casting the result of new Logger(...) in the full file, I managed to compile it. However, I still face the same error in my smaller test case.

Update 2: It seems that the error warnings disappear when the plugin highlighting syntax errors crashes. It appears that this method of object creation may not be allowed when "implicit any" is turned off.

Answer №1

A quick solution

interface IPerson {
    name: string;
}

var person = function(name: string) : void {
    this.name = name;
}

let funcPerson = <IPerson>(new (<any>(person("John Doe"))));

This code works fine with the noImplicitAny flag enabled.

An improved approach

You can simply convert the function into a class:

class person {
    constructor(public name: string) { }
}

let classPerson = person("John Doe");

After compilation, this becomes:

var person = (function () {
    function person(name) {
        this.name = name;
    }
    return person;
})();
var classPerson = new person("Jane Doe");

Converting the function to a class is beneficial for readability, refactoring, and future modifications. It provides better type information and eliminates the need for an interface in this case.

In summary, there is little reason to prefer the function version over the class implementation. Both yield equivalent objects (see classPerson and funcPerson).

Another alternative

If you want to use a working .js file with TypeScript, consider creating a .d.ts file like this:

person.js

var person = function(name) {
    this.name = name;
}

person.d.ts

interface PersonStatic {
    name:string;
    new(name: string) : PersonStatic;
}
declare var person: PersonStatic;

With this setup, you can do:

/// <reference path="your.d.ts"/>
var p = new person("Jane Doe");

Ensure that the person.js file is available at runtime for proper execution. The example .d.ts file provided is basic; if you pursue this option, it's recommended to learn more about creating .d.ts files beforehand.

Answer №2

Explain the structures of type and its constructor. Utilizing interfaces would be an ideal approach.

type PersonType = {
    name: string;
    greet: (otherPerson: PersonType) => string;
    selfIntroduce: () => string;
}

//When it comes to ordinary functions, they can be called with or without the "new" operator and
//the type of the constructor must specify both signatures

type PersonTypeConstructor = {
    (this: PersonType, name: string): void; //<- The use of "this" here is optional
    new(name: string): PersonType; // <- Do not include "this" here
}

Create the function meant for serving as the constructor. It is crucial to specify this as the initial parameter(since TS 2.0) in order to prevent compiler errors when the noImplicitThis flag is enabled.

const Person = (function Person(this: PersonType, name: string) { 
    this.name = name;
}) as PersonTypeConstructor; // <- This casts the constructor making further casting unnecessary.

Person.prototype.greet = function (otherPerson: PersonType) {
    return `Hello, ${otherPerson.name}!`;
};

Person.prototype.selfIntroduce = function () {
    return `Hello, my name is ${this.name}.`;
};

let peggySue = new Person("Peggy Sue");
let maryAnn  = new Person("Mary Ann");

console.log(maryAnn.selfIntroduce());
console.log(peggySue.greet(maryAnn));

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

Stop webpack from stripping out the crypto module in the nodejs API

Working on a node-js API within an nx workspace, I encountered a challenge with using the core crypto node-js module. It seems like webpack might be stripping it out. The code snippet causing the issue is: crypto.getRandomValues(new Uint32Array(1))[0].toS ...

Enhancing Angular2 authentication with Auth0 for enabling Cross-Origin Resource Sharing

I have been working on implementing user authentication through Auth0. I followed the instructions provided on their website, but I am encountering authentication issues. Whenever I try to authenticate, an error message appears in the console stating that ...

Guide on implementing a cordova plugin in a TypeScript cordova application

In my Cordova project, which utilizes Angular and Typescript, I am facing issues with implementing the juspay-ec-sdk-plugin for Cordova. I have explored possible solutions on StackOverflow related to integrating Cordova plugin in an Angular 4 Typescript ...

The JSON.stringify method in TypeScript/JavaScript does not align with the json-String parameter or request body in a Java controller

Currently, I am utilizing jdk 1.8 and have a rest endpoint in my Java controller: @PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) String filter ) { try { ............... } } A test sn ...

The React namespace is missing the exported member 'InputHTMLAttributes', and the MenuItemProps interface is incorrectly extending the ListItemProps interface

I am currently working with Material-UI and typescript. I have installed the typescript types using npm install -D @types/material-ui. After loading my webpage, I encountered the following errors: ERROR in [at-loader] ./node_modules/@types/material ...

Exploring NuxtJS Vuex Module namespaces and mutation enumerations

My NuxtJS website has a Vuex store with a root state and a module located at store/shop/cart/state.ts. Within the module, there is a file called store/shop/cart/mutations.ts. import { MutationTree } from 'vuex'; import { CartState } from './ ...

The expect.objectContaining() function in Jest does not work properly when used in expect.toHaveBeenCalled()

Currently, I am working on writing a test to validate code that interacts with AWS DynamoDB using aws-sdk. Despite following a similar scenario outlined in the official documentation (https://jestjs.io/docs/en/expect#expectobjectcontainingobject), my asser ...

Pay attention to the input field once the hidden attribute is toggled off

In attempting to shift my attention to the input element following a click on the edit button, I designed the code below. The purpose of the edit is to change the hidden attribute to false. Here's what I attempted: editMyLink(i, currentState) { ...

Starting PM2 with multiple instances can be achieved by following these steps

While running my nodejs code with PM2, I encountered a requirement for multiple instances of nodejs executing the same code. To address this need, I created a script named "myscript.sh": cd ~/myproject PM2_HOME='.pm2_1' /usr/local/bin/node /u ...

data not corresponding to interface

I am encountering an issue that says Type '({ name: string; href: string; icon: IconDefinition; } | { name: string; href: string; icon: IconDefinition; childs: { name: string; href: string; icon: IconDefinition; }[]; })[]' is missing the followin ...

I am having issues with the Okta Angular sign-in widget as it is not redirecting

Recently, I integrated the Okta angular sign-in widget into my project, but I encountered an issue. In my application, I have multiple modules including an authentication module that manages sign-in, sign-out, and sign-up functionalities. The route I ult ...

How to Invoke a TypeScript Function in Angular 2 Using jQuery

Using the Bootstrap-select dropdown in Angular 2 forms with jQuery, I am attempting to call a Typescript method called onDropDownChangeChange on the onchange event. However, it seems to not be functioning as expected. import { Component, OnInit, ViewChi ...

Learn the steps to dynamically show a navbar component upon logging in without the need to refresh the page using Angular 12

After logging in successfully, I want to display a navbar on my landing page. Currently, the navbar only shows up if I reload the entire page after logging in. There must be a better way to achieve this without a full page reload. app.component.html <a ...

Angular 8 combined with Mmenu light JS

Looking for guidance on integrating the Mmenu light JS plugin into an Angular 8 project. Wondering where to incorporate the 'mmenu-light.js' code. Any insights or advice would be greatly appreciated. Thank you! ...

What is the importance of adding the ".js" extension when importing a custom module in Typescript?

This is a basic test involving async/await, where I have created a module with a simple class to handle delays mymodule.ts: export class foo { public async delay(t: number) { console.log("returning promise"); ...

Delete row from dx-pivot-grid

In my current project, I am utilizing Angular and Typescript along with the DevExtreme library. I have encountered a challenge while trying to remove specific rows from the PivotGrid in DevExtreme. According to the documentation and forum discussions I fo ...

The addition operator cannot be used with the Number type and the value of 1

Encountering an issue where the operator '+' cannot be applied to types 'Number' and '1' buildQuerySpec() { return { PageSize: this.paging.PageCount, CurrentPage: this.paging.PageIndex + 1, MaxSize: '' ...

Utilizing WebPack 5 in conjunction with Web workers in a React/Typescript environment

Can someone help me figure out how to make a web worker function properly with create-react-app, Typescript, and Webpack 5? I've been struggling with limited documentation and can't seem to find a clear explanation. I'm trying to avoid using ...

Refining types in a series of statements

I'm attempting to merge a series of assertions in a safe manner without the need to individually call each one. For instance, consider the following code: type Base = { id: string, name?: string, age?: number }; type WithName = { name: string }; type ...

Definition of TypeScript array properties

Having some trouble creating a type for an array with properties. Can't seem to figure out how to add typings to it, wondering if it's even possible. // Scale of font weights const fontWeights: FontWeights = [300, 400, 500]; // Font weight alia ...