Implementing an external abstract class in Typescript without inheriting from it

In my code, there is a module named utils.tsx defined as follows:

interface IUtils {
    toUri: (route: string) => string
}

export default abstract class Utils implements IUtils {
    public toUri = (route: string) => {
        return route
    }
}

Now, in another file where I want to utilize this utils module:

 import Utils from '../helpers/utils'

 class Router  {
     private getBuilder = (search: string) => {
       const path = Utils.toUri(search)
     }
 }

However, using Utils.toUri gives me a TS error:

[ts] Property 'toUri' does not exist on type 'typeof Utils'.

I aim to call the external abstract class function without extending or inheriting from the Router class since there will be multiple external modules in the main file. Can someone assist me in finding a solution and understanding this issue?

PS: I also attempted with public abstract toUri(). It's possible that I have confused the usage of static and abstract due to routines from other programming languages...

Answer №1

It is not advisable for Utils to implement IUtils, as Utils represents the instance type of the class. It seems that you intend for the constructor of Utils (with the type typeof Utils) to implement IUtils. This implies that toUri should be a static method in the Utils class, like so:

abstract class Utils {
  public static toUri = (route: string) => {
    return route
  }
}

There is no direct way to specify that the static part of the class implements IUtils in the class Utils declaration. However, due to structural typing, the Utils constructor will inherently be recognized as implementing IUtils without explicit annotation.

declare function takeIUtils(iUtils: IUtils): void;
takeIUtils(Utils); // works as expected

This approach should achieve the desired functionality for your Router class.


On a side note, consider whether having Utils as a class is necessary. If instances of Utils are unnecessary (e.g.,

class X extends Utils {...}; new X()
), it might be beneficial to treat Utils as a value:

export const Utils : IUtils = {
  toUri(route: string) {
    return route
  }
}

Alternatively, you could utilize a namespace structure:

export namespace Utils {
  export function toUri(route: string) {
    return route
  }
}

Consider these options or explore module-based solutions based on your requirements.


Hopefully, this information proves helpful. Best of luck with your implementation!

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

Angular 7 compile error NG8002: Unable to bind object as it is not recognized as a valid property

Currently working on an Angular 7/8 test App. Encountering a compile error Can't bind 'discounter' since it isn't a known property of 'paDiscountEditor' The HTML where the error is occurring is simple... Below are all the nec ...

Can you explain the distinction between "parser" and "parserOptions.parser" in an ESLint configuration?

For a considerable amount of time, I have been using the TypeScript and Vue presets provided below. While it has been functional, I realize that I do not fully comprehend each option and therefore seek to gain a better understanding. Firstly, what sets apa ...

Function that returns a lookup map for TypeScript enums

For my React project, I've created a function that transforms a lookup class into an array that can be used. The function is functioning properly, but it seems to loop through the enum twice, resulting in undefined values for the first iteration. Alt ...

Troubleshooting: Unable to Open Page with Google Material Button in Angular 5

Currently, I'm facing an issue with a button that is not opening to a new site despite following what seems like simple steps. <button mat-raised-button href="https://www.google.com/" color="primary">Connect with Stripe</button> I even a ...

Discussing recursive types A <--> B with generics in TypeScript

I'm currently working with the following TypeScript code: type DormNodePredicate = DormEdge | (() => DormNode<DormNodePredicateRecord>); interface DormNodePredicateRecord { [key: string]: DormNodePredicate; } export class DormNode<DNPR ...

The Mui datepicker displays the day and month in reverse order

Do you have trouble with date search filter using the mui datepicker component? It seems that when entering a date in the input and clicking on search, the day gets swapped with the month. For instance, if you input 03/05/2022, it returns Sat Mar 05 2022 ...

Ways to retrieve a value from outside the Angular subscribe block

Custom Template <div class="row" *ngFor="let otc of this.jsonData;index as j"> <div> <table class="table table-striped table-fixed"> <tr *ngFor="let opc of this.winServiceInfo ...

What is the best way to update the color of a label in a Mantine component?

When using the Mantine library, defining a checkbox is done like this: <Checkbox value="react" label="React"/> While it's possible to change the color of the checkbox itself, figuring out how to change the color of the label ...

The type '{ status: boolean; image: null; price: number; }[]' does not include all the properties required by the 'SelectedCustomImageType' type

While developing my Next.js 14 TypeScript application, I encountered the following error: Error in type checking: Type '{ status: boolean; image: null; price: number; }[]' is missing the properties 'status', 'image', and &apos ...

Tips for creating a versatile function in TypeScript that accepts either a single value or an array of values for two parameters

I'm currently working on a task to develop a versatile function that accepts a parameter called hashMapName, another parameter called 'keys' which can be either a string or an array of strings, and a callback function that will return either ...

Combine array elements in Angular/Javascript based on a certain condition

Is there a way to combine elements from two arrays while avoiding duplicates? array = [ {id: 1, name:'abc'},{id: 1, name:'xyz'},{id: 2, name:'text1'},{id: 2, name:'text2'} ]; The desired output is: result = [{id: ...

Angular - Showing validation messages post successful execution of two functions

I have encountered an issue with my form submission process involving two functions. When both functions succeed, I want to display a successful validation message. However, currently the success message is displayed even if the second function fails. How ...

The diameter of the pie chart in HighCharts adjusts dynamically based on the values specified within the series

I am currently utilizing HighCharts to display a doughnut (pie) chart in my Angular application. One issue I am facing is that the 'inner size' of the graph changes based on the values provided in the series. When the series has only two values, ...

I am perplexed by the CommonJS pattern, TypeScript modules, and how to effectively utilize ES6

Hey there, everyone! I'm curious if someone could provide me with a straightforward comparison of the development flow when working with CommonJS, Typescript, and ES6 in relation to the module import system (such as require(), import "xx", export), c ...

Is it possible in TypeScript to change a string literal type into a number type?

Would it be feasible to develop a utility type Number<T> that can take a string literal type and convert it into a number? If conversion is not possible, should the utility return a never type? type Five = Number<'5'> // `Five` is con ...

Encountered an issue with a module not being found while trying to install a published React component library that is built using Rollup. The error message states:

In my latest project, I have developed a React component library called '@b/b-core' and used Rollup for building and publishing to the repository. When trying to install the library in a React app, an issue arises where it shows Module not found: ...

Create a fresh instance of an object in node.js by utilizing the require/new method

I am encountering a beginner problem with node.js where I cannot seem to create objects using the 'new' operator in the index.js file. My goal is to define a simple Person object within a Person.js file, located in the same directory as my index ...

Running JavaScript code when the route changes in Angular 6

Currently, I am in the process of upgrading a website that was originally developed using vanilla JS and JQuery to a new UI built with Angular and typescript. Our site also utilizes piwik for monitoring client activity, and the piwik module was created i ...

The issue with Angular's Array.push method arises when only the last object in the array is being pushed after a mat-checkbox

I am currently working with two components called item-list and item. The item-list component is responsible for displaying a list of items with checkboxes. I have been facing an issue where the Array that stores the checked items only retains the last ite ...

The error message "TypeError: Attempting to access the 'map' property of an undefined value (React JS)" was displayed

I'm currently working on a recursive function that needs to iterate over an object type called ItemType. However, I encountered an error message: TypeError: Cannot read property 'map' of undefined This is the code snippet causing the issue: ...