Is there a method (hack) to instantiate an instance of class `T` within a generic class?

Is there a way or workaround to instantiate an object of type T within a generic class?

type Foo = { /*...*/ };

class Bar <
  T extends Foo  
> {
  public readonly foo: T;

   public constructor(
    init?: { foo: T } | undefined
  ) {
     this.foo = init?.foo ?? new T(); // ERROR: 'T' only refers to a type, but is being used as a value here.ts(2693)
  }
};

Answer №1

Yes, this solution was effective for me.

// ---- . ---- ---- ---- ---- . ----
// Custom Class Foo:
// ---- . ---- ---- ---- ---- . ----

type FooInit = {
  readonly prop01?: string | undefined;
};

type FooInterface =
  Required<FooInit>;

class Foo
  implements
    FooInterface
{
  public readonly prop01: string;

  public constructor(
    init?: FooInit | undefined
  ) {
    this.prop01 = init?.prop01 ?? "default prop01";
  }
};

// ---- . ---- ---- ---- ---- . ----
// Custom Class Bar:
// ---- . ---- ---- ---- ---- . ----

type BarInit <
  GenericFooInit extends FooInit
> = {
  readonly foo?: GenericFooInit | undefined
}

type BarInterface <
  GenericFoo extends Foo
> = {
  readonly foo: GenericFoo
}

class Bar <
  GenericFooInit extends FooInit,
  GenericFoo extends Foo
>
  implements
    BarInterface<GenericFoo>
{
  public readonly foo: GenericFoo;

  public constructor(
    GenericFooConstructor: new (
      init?: GenericFooInit | undefined
    ) => GenericFoo,
    init?: BarInit<GenericFooInit> | undefined
  ) {
    this.foo = new GenericFooConstructor(init?.foo);
  }

  // Custom method 'make'
  public static readonly make = <
    GenericFooInit extends FooInit,
    GenericFoo extends Foo
  > (
    GenericFooConstructor: new (
      init?: GenericFooInit | undefined
    ) => GenericFoo,
    init?: BarInit<GenericFooInit> | undefined
  ): Bar <
    GenericFooInit,
    GenericFoo
  > =>
    new Bar <
      GenericFooInit,
      GenericFoo
    > (
        GenericFooConstructor,
        init
    )
};

// ---- . ---- ---- ---- ---- . ----
// Example of Use:
// ---- . ---- ---- ---- ---- . ----

type NeoFooInit = FooInit & {
  prop02?: string | undefined;
};

type NeoFooInterface =
  Required<NeoFooInit>

class NeoFoo
  extends
    Foo
  implements
    NeoFooInterface
{
  public readonly prop02: string;

  public constructor(
    init?: NeoFooInit | undefined
  ) {
    super(init);
    this.prop02 = init?.prop02 ?? "default prop02";
  };
};

const bar01 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo);

const bar02 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {});

const bar03 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {
  foo: {}
});

const bar04 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {
  foo: {
    prop01: "prop01"
  }
});

const bar05 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {
  foo: {
    prop02: "prop02"
  }
});

const bar06 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {
  foo: {
    prop01: "prop01",
    prop02: "prop02"
  }
});

const bar07 = Bar.make <NeoFooInit, NeoFoo> (NeoFoo, {
  foo: {
    prop01: "prop01",
    prop02: "prop02",
    prop03: "prop03" // Generates error message as follows:
                     // Type '{ prop01: string; prop02: string; prop03: string; }' is not assignable to type 'NeoFooInit'. 
                     //   Object literal may only specify known properties, but 'prop03' does not exist in type 'NeoFooInit'. Did you mean to write `'prop01'`? ts(2322)
  }
});

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

How can we create a versatile Action type in typescript that can accommodate varying numbers of arguments and argument types?

When working with Typescript, encountering a duplicate type error can be frustrating. For instance, consider the following code snippet: export type Action<T> = (arg:T) => void export type Action<T1,T2> = (arg1:T1, arg2:T2) => void How c ...

Encountering an error while unit testing Angular components with MatDialog: "Error: <spyOn>: open has already been spied upon."

Once I create an HTML file with a button, I trigger a poll to appear after an onClick event. Then, when the "submit" button is clicked on the dialog window, it closes and I intend to execute subsequent methods. In my TypeScript file: openDialogWindow() { ...

Fire the props.onChange() function when the TextField component is blurred

Currently, I am in the process of developing a NumberField component that has unique functionality. This component is designed to remove the default 0 value when clicked on (onFocus), allowing users to input a number into an empty field. Upon clicking out ...

Maintaining the order of the returned values type is crucial when working with mapped objects in Typescript

Currently, I am developing a basic mapper function for objects. This function is designed to take an array of object properties and then return an array containing the corresponding values of these properties. The function works as intended; however, I hav ...

Utilize the class type of a method parameter as the method type for another parameter

Here's a quick example illustrating my desired functionality. // Every time, the ACL class will have a different name such as "UsersACL", etc. export class EventsACL { test(): { read: true, write: true } { } } // This function acts ...

Is there a way to establish a data type using a specific key within the Record<K, T> structure in Typescript?

Imagine the scenario where an object type needs to be created and linked to a specific key specified in Record<Keys, Type>. Let's say there is a type called User, which can have one of three values - user, admin, or moderator. A new type called ...

Guide on extracting just the key and its value from a Filter expression in a DynamoDB Query using Typescript

Presented here is a filter expression and Key Condition. The specific set of conditions are as follows: {"Age":{"eq":3},"Sex":{"eq":"MALE"}} const params: QueryCommandInput = { TableName: my_tab ...

Obtaining the host and port information from a mongoose Connection

Currently, I am utilizing mongoose v5.7.1 to connect to MongoDb in NodeJS and I need to retrieve the host and port of the Connection. However, TypeScript is throwing an error stating "Property 'host' does not exist on type 'Connection'. ...

"Learn the trick of converting a stream into an array seamlessly with RxJs.toArray function without the need to finish the

In order to allow users to filter data by passing IDs, I have created a subject that can send an array of GUIDs: selectedVacancies: Subject<string[]> = new Subject(); selectedVacancies.next(['a00652cd-c11e-465f-ac09-aa4d3ab056c9', ...

Guide on how to update an array within typed angular reactive forms

I'm currently working on finding a solution for patching a form array in a strongly-typed reactive Angular form. I've noticed that patchValue and setValue don't consistently work as expected with FormControl. Here's an example of the fo ...

Utilizing properties from the same object based on certain conditions

Here's a perplexing query that's been on my mind lately. I have this object with all the styles I need to apply to an element in my React app. const LinkStyle = { textDecoration : 'none', color : 'rgba(58, 62, 65, 1)', ...

The disabled attribute appears to be ineffective in an Angular reactive form

In my Angular reactive form, I have an email field that I want to disable when the form is in edit mode instead of add mode. The code I am using for this is: disabled: typeof user.user_id === 'string' When I debug the modelToForm method and che ...

Create a fresh array by merging two existing arrays together

My project involves working with two separate arrays. The first array contains normal date values: var = [ "2022-05-01", "2022-05-02", ... "2022-05-30" ] The second array consists of objects that contain s ...

The process of extracting a value from an array of objects encountered an error due to the undefined object

I am looking to extract the value from an array within an object while also implementing error checking. The code I currently have checks if a specific key exists in the object and if the value associated with that key is of type array. If both condition ...

There is no overload match for the HttpClient.get call at this time

I'm trying to set up a file download feature using a blob, but I need to extract the filename from the server's "content-disposition" header. Here's the code I have: const header = {Authorization: 'Bearer ' + token}; const config ...

Using Typescript to extract/calculate types with limitations without the need to explicitly extend or broaden them

I have a function called build that constructs a User object using the provided parameters. I want to define the function in such a way that it recognizes which parameters are being passed and incorporates them into the return value. Initially, I thought ...

After restoring my Windows system, I encountered an issue with locating the typescript.js module for my Angular app development. I am currently troubleshooting the build

My PC had some issues, so I decided to restore Windows to an older restoration point. However, after doing this, I encountered an error while trying to build my Angular App: C:\Udemy\AngularDeCeroAExpertoEdicion2021\03-paisesApp>npm run ...

Similar to the getState() function in react-redux, ngrx provides a similar method in Angular 6 with ngrx 6

Recently, I developed an application with react and redux where I used the getState() method to retrieve the state of the store and extract a specific slice using destructuring. Here's an example: const { user } = getState(); Now, I am transitioning ...

Unable to find solutions for all parameters of the TemlComponent: (?). encountering a syntax error (compiler.js:1016)

As a beginner in Angular, I'm struggling to pinpoint the error in my code and understand why I'm encountering this issue. The error message reads: "Can't resolve all parameters for TemlComponent: (?). at syntaxError (compiler.js:1016)." To ...

What is the most effective way to utilize getStaticPaths in a dynamic manner within next.js

There is a need to paginate static pages for each of the 3 blog categories, but the problem lies in the variable number of pages and the inability to access which category needs to be fetched in getStaticPaths. The project folder structure appears as foll ...