How to create classes in typescript without utilizing the class keyword

As someone new to TypeScript, I have a curious question about classes.

In pre-ES6 JavaScript, there were no classes. So, naturally, one would think it's possible to avoid using them in TypeScript as well.

However, I am struggling to figure out the correct approach. Consider this sample class:

class FooConcrete {
    getImpl : () => number;

    constructor(getImpl: () => number) {
        this.getImpl = getImpl;
    }

    get() : number {
        return this.getImpl();
    }
}

When looking at typical type definition files, they expose something like this:

interface FooConcrete
{
    get() : number;
}

interface FooConcreteStatic
{
    new () : FooConcrete;
}

Now, how do I define the FooConcrete constructor function?

I attempted:

var FooConcrete : FooConcreteStatic = function FooConcrete() {
    return {
        get: () => 42
    };
};

Unfortunately, that doesn't compile, even though the corresponding JavaScript code functions correctly:

new FooConcrete().get() // => 42

Is there a way to declare FooConcrete as FooConcreteStatic without using a class?

(My curiosity about this stemmed from wondering if it's possible to eliminate the unnecessary redirection in the class from the prototype's get to the implementation getImpl - in this scenario, a get in a prototype is not needed.)

Answer №1

It seems like manipulating the compiler is necessary in order to achieve that, as the language automatically handles tasks when classes are utilized.

This is an example of a TypeScript class:

class FooConcrete {
    getImpl : () => number;

    constructor(getImpl: () => number) {
        this.getImpl = getImpl;
    }

    get() : number {
        return this.getImpl();
    }
}

When targeting es5, the above code compiles into:

var FooConcrete = (function () {
    function FooConcrete(getImpl) {
        this.getImpl = getImpl;
    }
    FooConcrete.prototype.get = function () {
        return this.getImpl();
    };
    return FooConcrete;
}());

The corresponding definition file looks like this:

declare class FooConcrete {
    getImpl: () => number;
    constructor(getImpl: () => number);
    get(): number;
}

With this method, the JavaScript output aligns with the intended functionality and allows for compiling into either es5 or es6 classes seamlessly.

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

Animate in Angular using transform without requiring absolute positioning after the animation is completed

Attempting to incorporate some fancy animations into my project, but running into layout issues when using position: absolute for the animation with transform. export function SlideLeft() { return trigger('slideLeft', [ state('void&a ...

Endless cycle of NGRX dispatching

I tried creating a simple ngrx project to test the store, but I encountered an infinite loop issue. Even after attempting to mimic other examples that do not have this problem. To begin with, I defined 2 class models as shown below: export interface IBookR ...

Comparing Input and Output Event Binding

Can you provide reasons why using @Output for events is more advantageous than passing an @Input function in Angular 2+? Utilizing @Input: Parent Template: <my-component [customEventFunction]=myFunction></my-component> Inside parent-compone ...

Instead of relying on Vue TypeScript, we are leveraging IntelliJ with TypeScript 5.0.3 to compile our Vue project

My current version of IntelliJ IDEA is 2023.1 (Ultimate Edition) Build #IU-231.8109.175, released on March 28, 2023. I am facing an issue where my project fails to compile using "Vue TypeScript", resulting in some type mismatches being overlooked. In the ...

Create a custom component that wraps the Material-UI TextField component and includes default

I have been exploring React and had a question regarding wrapping a component like TextField from mui to add new props along with the existing ones. I attempted to do this but am struggling to figure out how to access the other props. Can anyone help me ...

Every time I execute my program, it consistently displays a 500 error message when using both the POST and GET

I'm seeking assistance with mvvm as I am new to it. Can anyone help me in displaying details based on the selected date? Upon running my code, I encounter a 500 error with both the post and get methods. Schedule.cshtml <div class="col-lg-8" ng-ap ...

Hiding a specific tag with vanilla JavaScript based on its content

I am facing a challenge with my code that is supposed to hide div elements containing a specific word along with additional text. I have tried multiple solutions but none seem to work effectively. Any assistance on how to hide divs properly will be greatl ...

retrieve the state property from NavLink

I am encountering an issue with passing objects through components in my project. Specifically, I have a chat object within a component that defines a NavLink. When a user clicks on the ChatsElement, which is a link, the page navigates to the URL /friends/ ...

What is the process for extracting the "path expression" from an interface in TypeScript?

My goal is to achieve the following structure: type Post = { id: number title: string author: { name: string } comments: { text: string }[] } type ExtractPathExpressions<T> = ??? type Paths = ExtractPathExpressions<Post> / ...

Validating patterns in Angular without using a form

Seeking guidance on validating user input in Angular6 PrimeNG pInputText for a specific URL pattern, such as , possibly triggered on blur event. This particular field used to be part of a form but has since been relocated to a more complex 6-part form int ...

What is the best way to pass a state within a route component in react-router?

... import { useNavigate, NavigateFunction } from "react-router"; ... function Form(): JSX.Element { const navigateToCountry = (country: string) => { // Code to navigate to country page with the given country } const [selectedCount ...

TSX is throwing an error: "No matching overload found for this call."

Just starting out with React and TypeScript here! I tried passing the propTypes into a styled-component and ran into this error message: Oh no, there's an issue with the overloads. Overload 1 of 2 seems to be missing some properties. Overload 2 of ...

Upon completion of a promise in an express middleware and breaking out of a loop, a 404 error is returned

In my efforts to retrieve an array of object (car) from express using database functions in conjunction with the stolenCarDb object, everything seems to be working fine. However, when attempting the following code snippet, it results in a 404 error w ...

What could be preventing my state from changing to false when I click the close button on the menu?

Despite initializing my state to false, the problem arises when I open and close my menu. The state never actually becomes false, causing the closing animation of the NavBar to not run as expected. The component: import CloseButton from "./CloseButto ...

In TypeScript, what specific term denotes a type of data?

Given the following code snippet: class Foo { } interface TypeProvider() { type(): ?; } class Bar implements TypeProvider { type(): ? { return (Foo); } } class Baz implements TypeProvider { type(): ? { return (Bar); ...

Tips for showcasing JSON data in an HTML table or list

I am seeking a way to dynamically display changing JSON object data in a table using Angular. The structure of the JSON object is subject to change due to server updates. JSON Object: { "This item has 1 value":1, "Another":30, "It ...

Having trouble with importing files from a different folder in a React Typescript project

I have a specific folder arrangement set up https://i.sstatic.net/GFOYv.png My goal is to bring both MessageList.tsx and MessageSent.tsx into my Chat.tsx file // Chat.tsx import React from 'react' import {MessageList, MessageSent} from "./ ...

Guide on importing a markdown file (.md) into a TypeScript project

I've been attempting to import readme files in TypeScript, but I keep encountering the error message "module not found." Here is my TypeScript code: import * as readme from "./README.md"; // I'm receiving an error saying module not found I als ...

Exploring TypeScript's type checking functionality

I've been pondering about the concept of type guards in TypeScript, particularly regarding their necessity when only one type is defined in a method signature. Most examples in the TypeScript documentation focus on scenarios involving union types, lik ...

Issues with Angular not reflecting data changes in the view after updates have occurred

I have a setup with two components. One is responsible for creating new data entries, while the other one is in charge of listing all the data stored in a database. The issue I'm facing is that even though the creation component successfully adds new ...