What is the significance of `new?()` in TypeScript?

Here is a snippet of code I'm working with in the TypeScript playground:


interface IFoo {
    new?(): string;
}

class Foo implements IFoo {
    new() {
     return 'sss'; 
    }
}

I noticed that I have to include "?" in the interface method "new" to avoid a compile error, but I'm not sure why.

Update: The original question may not be the best approach for using "new," so I've provided a more practical example below:


interface IUser {
  id: number;
  name: string;
}

interface UserConstructable {
  new (id: number, name: string, ...keys: any[]): IUser;
}

class User implements IUser {
  constructor(public id: number, public name: string) {

  }
}

class Employee implements IUser {
  constructor(public id: number, public name: string, private manager: string) {

  }
}

class UserFactory {
   private static _idx: number = 0;
   
   static makeUser(n: UserConstructable): IUser {
      let newId = UserFactory._idx++;
      
      return new n(newId, 'user-' + newId, 'manager-' + newId);
   } 
}

console.log(UserFactory.makeUser(User));
console.log(UserFactory.makeUser(User));
console.log(UserFactory.makeUser(Employee));

Answer №1

Splitting this up into a few sections... I understand that you may already be familiar with some of this, but I want to cover all the details.

1..2.3..4
new?():string;
  1. In this particular scenario, new is not considered a keyword; it's simply a method name... as explained in the next point...

  2. The ? signifies that this method is optional (meaning you can implement the interface without including this method).

  3. The () denotes that new is a method.

  4. The return type for this method is a string.

For instance

class Foo implements IFoo {
    new() {
        return 'sss'; 
    }
}

class Bar implements IFoo {
    // Since new is optional, there's no need to implement it
}

If you remove the ?, then new would function as a keyword - however, TypeScript interprets it as a regular method in your example.

Overall, it's advisable to avoid naming a member with something that resembles a reserved word.

Answer №2

When working with JavaScript, it's important to remember that functions are treated as objects. As a result, TypeScript interfaces must be able to accommodate these functions in order to properly define their behavior. This is why we often encounter unusual interfaces in our code.

interface SomeFunc {
  (key: string): boolean;
  (key: number): boolean;
}

The above interface specifies that it will only match functions accepting either a string or a number parameter and returning a boolean value.

Now let's consider the scenario of constructor functions, particularly in ES5 classes.

function MyClass() {
  this.prop = value;
}
let myClass = new MyClass;

In order to create an interface that aligns with the signature of the MyClass function, we utilize the new keyword within interfaces.

interface IFoo {
  new (key: string): {key:string};
}

function someFunction(key: string) { // does not match IFoo
  return {key};
}

var someObject = { // still does not match IFoo
  new(key: string) { 
    return {key};
  },
};

function MyClass(key: string) { // matches IFoo and needs to be called like `new MyClass()`
  this.key = key;
}

This illustrates that the function signature of new must correspond with the constructor function's signature.

interface IFoo {
  new(key: string): {};
}
class Foo implements IFoo { // successfully implemented
  constructor(key: string) { // unable to return any value
  }
}

If you're aiming to achieve a specific goal, such as:

interface IFoo {
  new: () => string;
}

It means defining a property named new within IFoo which should be a function returning a string.

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

Tips for preventing repetition in http subscribe blocks across various components

Imagine a scenario where there is a service used for making HTTP request calls. There are two different components (which could be more than two) that need to send the same request using the same observables via this service. After receiving the result, it ...

Just made the switch to Mongoose 5.12 and hit a snag - unable to use findOneAndUpdate with the $push operator

After upgrading to Mongoose 5.12 from 5.11 and incorporating Typescript, I encountered an issue with my schema: const MyFileSchema = new Schema<IMyFile>({ objectID: { type: String, required: true }, attachments: { type: Array, required: false ...

The Next.js template generated using "npx create-react-app ..." is unable to start on Netlify

My project consists solely of the "npx create-react-app ..." output. To recreate it, simply run "npx create-react-app [project name]" in your terminal, replacing [project name] with your desired project name. Attempting to deploy it on Netlify Sites like ...

Unsure about module loading with system.js and navigating Typescript

I am currently in the process of transitioning an ASP.Net MVC application to Angular2, and I've encountered some perplexing behavior that I can't seem to grasp. Within my Angular2 app, I have a separate Layoutview that allows me to switch betwee ...

The ongoing ESLint conundrum: Balancing between "Unused variable" and "Unknown type" errors when utilizing imports for type annotations

I've encountered a linting issue and I need some guidance on how to resolve it. Here's the scenario - when running $ yarn lint -v yarn run v1.22.4 $ eslint . -v v6.8.0 With plugins vue and @typescript-eslint, I have the following code in a .ts ...

How should I proceed if a TypeScript definition file that I am relying on is lacking a specific definition?

I have encountered an issue while using the React type definitions for my project. The focus method is missing on elements in the array returned by the refs property, which prevents me from getting a specific example to work. The compiler error states: pro ...

Tips for extracting specific JSON response data from an array in TypeScript

I have an array named ReservationResponse, which represents a successful response retrieved from an API call. The code snippet below demonstrates how it is fetched: const ReservationResponse = await this.service.getReservation(this.username.value); The st ...

Utilizing the subclass type as a parameter in inheritance

Looking for a way to restrict a function in C# to only accept classes of a specific base class type? In my current implementation, I have a base class (which can also be an interface) and n-classes that extend it. Here is what I am currently doing: abstr ...

Combining Rxjs map and filter to extract countries and their corresponding states from a JSON dataset

I have a unique dataset in JSON format that includes information about countries and states. For example: { "countries": [ { "id": 1, "name": "United States" }, { "id": 2, "name": "India" }], "states": [ { ...

tips for resolving pm2 issue in cluster mode when using ts-node

I'm having an issue using pm2 with ts-node for deployment. Whenever I try to use cluster-mode, a pm2 instance error occurs, saying "Cannot find module..." Error: Cannot find module '{path}/start' at main ({path}/node_modules/ts-node/dist/b ...

Tips for adding items to a Form Array in Angular

I am working on a project with dynamic checkboxes that retrieve data from an API. Below is the HTML file: <form [formGroup]="form" (ngSubmit)="submit()"> <label formArrayName="summons" *ngFor="let order of form.controls.summons.controls; let i ...

TypeScript throws an error when attempting to call a user-defined event handling function

I have created a custom event handling function like this: /** Trigger an event when clicking outside of a specific node */ export function eventHandlers(node: HTMLElement) { const handleClick = (event: MouseEvent) => { if (node && ...

The module ~/assets/images/flags/undefined.png could not be found in the directory

When I use the img tag with a dynamic address filled using require, it works well in the component. However, when I try to write a test for it, an error is thrown. console.error Error: Configuration error: Could not locate module ~/assets/ima ...

Progressive series of observable conditions

The issue at hand: I am faced with the task of checking multiple conditions, some of which lead to the same outcome. Here is the current flow: First, I check if a form is saved locally If it is saved locally, I display text 1 to the user If not saved l ...

In the event that you encounter various version formats during your work

Suppose I have a number in the format Example "1.0.0.0". If I want to increase it to the next version, it would be "1.0.0.1" By using the following regex code snippet, we can achieve this perfect result of incrementing the version to "1.0.0.1": let ver ...

Formik QR code reader button that triggers its own submission

I recently developed a custom QR code reader feature as a button within the Formik component customTextInput.tsx, but I encountered an issue where clicking on the button would trigger a submission without any value present. The following code snippet show ...

Encountering a Circular JSON stringify error on Nest.js without a useful stack trace

My application is being plagued by this critical error in production: /usr/src/app/node_modules/@nestjs/common/services/console-logger.service.js:137 ? `${this.colorize('Object:', logLevel)}\n${JSON.stringify(message, (key, value ...

What is the process for declaring a set in typescript?

In the documentation on basic types for Typescript, it explains using Arrays as a primitive type I am interested in the syntax: const numbers: string[] = [] How can I achieve the same with a set? ...

Utilizing Variables in TypeScript to Enhance String Literal Types

Here are my codes: export const LOAD_USERS = 'LOAD_USERS'; export const CREATE_USER = 'CREATE_USER'; export interface ACTION { type: string, payload: any } I am trying to limit the possible values for ACTION.type to either 'L ...

Issue with Angular 2 Routing: Unable to find a matching route

Currently, I'm in the process of developing an Angular 2+ application that requires routing. One of the requirements is for the color scheme of the entire app to change based on a URL parameter input. In my app.module.ts file, I have the following co ...