What is the process for coding a prototype-based ES5 class in TypeScript?

Currently, I am in the process of migrating some legacy ES5 projects to TypeScript. These projects contain older-style classes (functions) defined as shown in the simplified examples below:

function MyClass(arg1) {
  this.arg_prop_1 = arg1;
  this.arg_prop_2 = function() { return this.arg_prop_1; }
}

MyClass.prototype.proto_prop = function() { return this.arg_prop_2() === 42; }

const obj = new MyClass(42);
console.assert(obj.proto_prop());
 

I am seeking advice on the correct / recommended / best way to provide typings for this code without converting it into ES6 class syntax.



My Attempts So Far:

In order to implement TypeScript, I have declared certain interfaces like this (not working):

interface MyClassThis {
  arg_prop_1: number;
  arg_prop_2: () => number;
  proto_prop: () => boolean;
}

interface MyClassCtor {
  new (arg1: number): MyClassThis;
}

To start off, I tried using existing type definitions for the "Date" type from here. Since the above approach is not working (error: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.(7009)), I am still uncertain about the correct method to define types for these old-style class functions.

Answer №1

If you're unable to modify the source code, keep it as a .js file and include a corresponding .d.ts file with type definitions.

// my-class.js
export function MyClass(arg1) {
  this.arg_prop_1 = arg1;
  this.arg_prop_2 = function () {
    return this.arg_prop_1;
  };
}

MyClass.prototype.proto_prop = function () {
  return this.arg_prop_2() === 42;
};
// my-class.d.ts
export interface MyClass {
  arg_prop_1: string;
  arg_prop_2(): string;
  proto_prop(): boolean;
}

export const MyClass: {
  new (arg1: string): MyClass;
};

You can now utilize the file with these defined types:

import { MyClass } from "./my-class";

const instance = new MyClass("a string");
instance.proto_prop(); // returns a boolean value

View Code Sandbox Example

Answer №2

Although it's a bit overdue, I wanted to share this answer for anyone who may come across it in the future.

Alex Wayne's response provides insight on incorporating type definitions without altering your current codebase. However, if your intention is to transition to Typescript while maintaining compatibility with ES5 output, you can simply achieve this by including

"target": "es5"
in your tsconfig.json (documentation).

{
  // ...
  "compilerOptions": {
    "target": "es5",
    // ...
  }
}

In terms of defining your "ES5 class" in Typescript,

class MyClass {
  arg_prop_1: number;
  arg_prop_2: () => number;

  constructor(arg1: number) {
    this.arg_prop_1 = arg1;
    this.arg_prop_2 = () => this.arg_prop_1;
  }
  
  proto_prop() { return this.arg_prop_2() === 42; }
}

You can compare the compiled result to your original code here.

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

Using Typescript to implement a conditional return type and ensuring that the value types are consistent together

I am working with a useSelectedToggle hook that helps in connecting the UI state to the open/closed status of a dialog where it will be displayed. The toggle defines the value as (T) when it is open, and null when it is closed. How can I enforce stricter ...

Reorganizing a list in AngularJS after adding a new item

I have made edits to the AngularJS ordering example in my Plunker. The ordering works fine initially, but when I add a new person using code to periodically update the list of contacts, the new person gets added to the bottom without re-sorting. Is there a ...

Is there a comparable method to hasAttribute() in AngularJS?

Is there a way in a directive to check if an element has a specific attribute before performing a function on it? I couldn't find anything related to this in the jqLite documentation. For example: .directive('noReadonly', function() ...

Passing PHP array to JavaScript and selecting random images from the array

Check out my PHP script below: <?php $all_images = glob("Images/Classes/{*.png, *.PNG}", GLOB_BRACE); echo json_encode($all_images); shuffle($all_images); ?> Here's the JavaScript code I'm using: functio ...

How can I extract the text enclosed in <li> tags using JavaScript?

Can someone help me with retrieving the text content of li tags? I managed to get a list of lis, but I'm having trouble assigning the text content to my country object. Snippet var lis = document.getElementById("navbar").getElementsByTagName("l ...

What is the process for defining a filename when exporting with Webdatarocks default settings?

I'm having a hard time figuring out how to set a custom name for the exported file instead of just "Pivot". The HTML/Vue part contains the Pivot along with a select dropdown for filtering by date, which is working fine. The issue lies in customizing t ...

I was looking to implement back face culling for my sphere model, but I'm currently struggling with defining the vertices for my wireframe sphere

Currently, I am stuck while creating a wireframe sphere object and defining vertices for it. Additionally, I need help with applying back-face culling to the created sphere. Can anyone assist me with this task? In my HTML file, I have been using the three ...

Setting a Javascript value to a Controller variable within an ASP.NET MVC View

I am trying to set the javascript variable contentArea to match content.Contents in my controller. How can this be accomplished? <script language="javascript" type="text/javascript"> $("#btnTest").click(function () { var content ...

Converting CSV to JSON with the help of jQuery

I have a file in CSV format that looks like this: info,value "off to home","now" "off to office","tomorrow" I am trying to convert this data into JSON using jQuery, but I can't seem to find any help. Is it even possible to achieve this using jQuery? ...

How can I apply a class to the pre and code elements in Redactor?

I've been struggling for days to figure out how to add a class to the formatting option element within Redactor. By default, the "Code" formatting option wraps content in either <pre></pre> or <code></code> HTML elements. Howe ...

I am encountering compilation errors while trying to run a basic react-dnd list using typescript

I'm currently working on implementing the beautiful-react-dnd example and encountering some errors: import * as React from 'react'; import { DragDropContext, Draggable, Droppable, DroppableProvided, DraggableLocation, DropResult, ...

What could be the possible reason for the token having a null value during login authentication in

As a beginner to Angular, I am facing an issue with my JWT login page implementation. Despite printing the token in the console and confirming its existence as a string, I am receiving a null (or undefined) value. This is the code snippet from my UserServi ...

Numerous unique designs paired with exclusive paths

I am working on setting up a system that accommodates multiple layout variations and includes private routes to display specific content based on the user's login status and assigned layout. Currently, I have three different layouts in place, with the ...

Using type values in TypeScript

I am trying to assign interfaces as values within a config object: export interface RouterConfig { startEvents?: typeof RouterEvent[]; completeEvents?: typeof RouterEvent[]; } The intended usage is as follows: private config: RouterConfig = { star ...

Validating multiple fields that are added dynamically using jQuery

I am facing an issue with form validation using jQuery. The problem is that when one field is valid, the form gets submitted automatically. Here is a link to my code: http://jsfiddle.net/cvL0ymu7/. How can I ensure that all fields are validated before subm ...

Dealing with automatic indentation in the Node.js REPL while pasting content

I'm in search of a general idea on how to tackle the issue at hand. I currently have two REPLs - one for my Scheme based LISP written in JavaScript called LIPS, and another one using node.js with readline. The final problem that requires solving is ad ...

Unable to successfully transfer parameters from AJAX to PHP

I successfully utilized Jquery UI to update the position of my table. Now, I am trying to pass a parameter from AJAX to PHP in order to update my database with the current table position. However, I encountered an issue where I receive a TypeError: data=nu ...

What is the behavior of an AngularJS controller when it encounters the res.json(false) value?

In my AngularJS controller, I am sending an HTTP request to an API. The API can respond with either res.json(true) or res.json(false) depending on a certain condition. However, it seems like the controller is not handling this as expected. I am interested ...

Utilizing Restangular to assign multiple parameters to a variable within the scope variable

Currently learning AngularJS and utilizing Restangular to communicate with a Rails server API. Struggling with grasping the concept of assigning form parameters to a variable in order to use it within my function for posting to the Rails API. Below is an ...

Utilizing ScrollTo() in Javascript will smoothly navigate the page downward

Within my HTML Document, there lies an input field where you can enter a numerical value, and the window should automatically scroll to that specific pixel number. To achieve this, I utilized the scrollTo() function. However, I encountered an issue where ...