Make a new subclass from a class in TypeScript, but exclude the constructor function

Below is the interface and class definition that I have created:

interface Example {
  constructor: typeof Example;
}

class Example {
  static sample = 'sample';

  constructor(data: Partial<Example>) {
    Object.assign(this, data);
  }

  someFunction() {
    return this.constructor.sample;
  }

  prop1: string;
  prop2: number;
}

The necessity of the interface is to ensure that this.constructor has a strong type. However, it poses an issue when trying to pass a plain object into the class constructor:

const instance = new Example({ prop1: 'abcd', prop2: 5678 });

// Argument of type '{ prop1: string; prop2: number; }' is not assignable to parameter of type 'Partial<Example>'.
// Types of property 'constructor' are incompatible.
// Type 'Function' is not assignable to type 'typeof Example'.
// Type 'Function' does not match the signature 'new (data: Partial<Example>): Example'.

I am aware of the error message, but I am unsure of how to resolve it. Is there a way to use Partial<Example> to allow passing a plain object? Here's a playground link for reference:

Playground

Answer №1

Below is an example demonstrating how to create a derived type from a class without including the constructor and only keeping regular methods:

type NonConstructorKeys<T> = ({[P in keyof T]: T[P] extends new () => any ? never : P })[keyof T];
type NonConstructor<T> = Pick<T, NonConstructorKeys<T>>;

Here is how you can use it with the Foo class mentioned in the question:

type FooNonConstructorKeys = NonConstructorKeys<Foo>; // "prop1" | "prop2" | "someMethod"
type FooNonConstructor = NonConstructor<Foo>;

Answer №2

I stumbled upon the perfect solution in this exceptional response:

how to remove properties via mapped type in TypeScript

The snippet provided in the answer constructs a new type that includes only methods. However, my requirement was to achieve the opposite. The utility function NonMethods<T> accomplishes this by creating a derived type where all methods are excluded.

type NonMethodKeys<T> = ({[P in keyof T]: T[P] extends Function ? never : P })[keyof T];  
type NonMethods<T> = Pick<T, NonMethodKeys<T>>; 

Explore on Playground

Answer №3

It appears that you are interested in creating an interface and utilizing it in your code. To achieve this, you need to define the properties within the interface itself instead of the class.

interface Bar {
  attribute1: string; // Define properties here
  attribute2: number;
}

class Bar {
  static baz = 'baz';

  constructor(data: Partial<Bar>) {
    Object.assign(this, data);
  }

  someFunction() {
    return Bar.baz; // Accessing static variables
  }

}

const bar = new Bar({ attribute1: 'xyz', attribute2: 5678 });

Playground

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

Making Mat-Tab Table Headers Sticky in Angular

I'm facing an issue in my application where I have a screen with 3 tabs. One of these tabs contains a table with a large number of rows, and I want to make the headers of this table sticky so that they remain visible when the user scrolls down. Despit ...

Developing a special cookie to store the initial visit's home page location

Trying to set up a user flow like so: User clicks "save my textbook" link to save a cookie and receive an alert that it was saved Upon revisiting the homepage, jQuery checks for the cookie value corresponding to the textbook they saved If the cookie exis ...

The dropdown menu in Mantine is malfunctioning, even though I copied and pasted the exact code from

While following a tutorial, I encountered an issue with the Mantine Menu and Dropdown components. The tutorial creator did not wrap the React App inside the MantineProvider, which resulted in errors when trying to use the Dropdown component. Even after add ...

Determine the existence of a document/record in MongoDB

I am having trouble using .find({}) with MongoDB as it is not returning the expected response. I'm not sure how to determine if the document exists or not. What I want to achieve is: If a document exists, then do something - like sending a response b ...

Interactive canvas feature in a browser window with scrolling capabilities (drag and drop functionality)

One challenge I'm facing is when drawing in a canvas on a browser window that has a vertical scrollbar. The figures are in the correct position, and it's possible to interact with them by grabbing and making connections. However, this interactio ...

What is the best way to incorporate the TUI image editor for Javascript into my Angular application?

Issue - I'm facing a challenge with my Angular application as I want to integrate Toast UI image editor. However, I am unsure about how to properly add the imports to app.module.ts in order to utilize it. Despite following the npm installation instru ...

I'm having trouble with my vue props, can you lend a hand in resolving them

Recently, I delved into learning Vue.js and started implementing it in my project. The code snippet in my App.vue file is: In the second line of the code above, I passed a string "hello" as an attribute that is captured in the following code: App.vue: ...

Incorporate a Popup Feature in a React Heatmap Grid

I am implementing react-heatmap-grid to generate a data table and I would like to have a popup open when I click on a square within the table. Since my project uses Semantic UI, I want to utilize the Pinned Popup feature that only appears upon clicking. T ...

"Utilize Chart Bars in CodeIgniter 3 for Dynamic Data Representation

In my quest to showcase the latest additions to my database, I am looking to create a visually appealing chart using bar graphs. This will help me list out the new records along with the respective months of addition. The hurdle that stands in my way is t ...

Step-by-step guide on incorporating an external library into Microsoft's Power BI developer tools and exporting it in PBIVIZ format

I'm attempting to create a unique visualization in PowerBI using pykcharts.js, but I'm running into issues importing my pykcharts.js file into the developer tool's console. I've tried including a CDN path like this: /// <reference p ...

Manipulating and filtering an array of objects in JavaScript/jQuery

Looking to simplify my array manipulation in Javascript, I need to subset based on key-value matches. I have an array called js_obj, and my goal is to modify objects where a certain condition is met. Consider the structure of my array: js_obj = [{ wo ...

Tips for troubleshooting ImageArray loading issues in AngularJS

Having some trouble learning Angular and getting stuck with this Image array. Can someone please help me understand what's wrong with my code and how to fix it? FilterAndImages.html <!DOCTYPE html> <html ng-app="store"> <head> < ...

Error: JavaScript object array failing to import properly

In my code, I have an array of objects named trace which is defined as follows: export const trace: IStackTrace[] = [ { ordered_globals: ["c"], stdout: "", func_name: "<module>", stack_to_render: [], globals: { c: ["REF" ...

Encountering a discord bot malfunction while on my Ubuntu server

My discord bot runs smoothly on my Windows 10 setup, but when deployed to the server running Ubuntu Server 20, it encounters a specific error. The issue arises when trying to handle incoming chat messages from the server. While I can read and respond to m ...

Setting the column width and border-top in Highcharts

Hey there, I'm facing an issue with my highcharts diagram. 1) Can anyone help me adjust the column width to match the width of the month area? (I've tried changing "width" in CSS but it's not working) 2) Also, how can I remove all borders ...

Using PHP variables in JavaScript is not compatible

Currently, I am facing an issue where PHP variables inside the javascript code are not being echoed. When I try to echo the variables outside of the javascript, everything works perfectly fine. After carefully reviewing my code multiple times, I still cann ...

Unable to achieve autofocus functionality with the Directive feature on Firefox browser

I created a custom directive that wasn't functioning properly on Firefox version 36.00. It's supposed to work similarly to the autofocus attribute in HTML 5. Here is the directive code: app.directive('autoFocus', function($timeout) { ...

Is it necessary for me to use NG-IF / NG-SWITCH or should I opt for NG-SHOW & NG-HIDE instead?

I'm facing a frustrating dilemma because I am unsure of the best approach to take in this scenario. Below is the basic setup: I aim to display the current status of a movie, which will have different messages in the DOM based on its state. A movie ca ...

Attach a click event to a dynamically generated element inside a directive

After thinking I had successfully solved this issue, it turns out I was mistaken. I developed a directive to enable me to clear a text input field. Essentially, when you begin typing into the input box, an "X" icon appears on the right side of the textbox. ...

Asynchronous function failing to pause execution at await

My async functions are causing issues after recently switching from Mocha to Jest. Previously, my code would await the import of a JSON file and then manipulate the data sequentially. However, since the migration, all my tests and functions are breaking. ...