Challenges with TypeScript's typeof operator and instantiation of classess

Discussing the scenario of a map setup:

  const map = {
    a: ClassA,
    b: ClassB,
    c: ClassC,
  }

The purpose of this map is to link different classes together. There exists a function that returns an instance of a class based on a key in the map object:

const conf = {};

type VersionMap = typeof map;
type Versions = keyof VersionMap;

const getter = <T extends Versions>(ver: T): VersionMap[T] => new map[ver](conf);

An issue arises where typeof references the class constructor instead of an instance, leading to an error. How can this problem be resolved without creating a second type?

Answer №1

It seems there may be a slight misunderstanding regarding how classes are categorized. Let's consider, for simplicity's sake, two classes ClassA and ClassB.

class ClassA {
  constructor() {
    console.log("Class A");
  }
}

class ClassB {
  constructor() {
    console.log("Class B");
  }
}

Creating the map object is straightforward, but it might have been helpful to outline an interface specifying what this object should contain. However, following your example, I will proceed without one.

const map = {
  a: ClassA,
  b: ClassB,
};

Now comes the challenging part - Typings. Firstly, I aim to extract all keys of the map object. For this purpose, I will define a new type called: Keys

// Type includes: "a" | "b"
type Keys = keyof typeof map;

Next, I need all the corresponding values for each key. To achieve this, I will create a new type at the index of Keys.

// Type includes: typeof ClassA | typeof ClassB
type Values = typeof map[Keys];

The getter function should return an instance of a class T. However, the Values type contains all classes as typeof ClassA | typeof ClassB, which translates to

new() => ClassA | new() => ClassB
. Therefore, the type of ClassA | ClassB is not compatible.

To address this, let's create a separate type to resolve the issue. This type should yield the instance type of a class - simply ClassA or ClassB. In other words, the return type of the new SomeClass() operation.

type ReturnType<T> = T extends new() => infer R ? R : never;

If you wish to learn more about conditional types in TypeScript, I recommend checking out this blog post: Let's incorporate the final piece:

const conf = {};
const getter = (ver: Keys): ReturnType<Values> => new map[ver]();

Just a heads up: I renamed VersionMap to Values and Version to Keys for clarity on their intended purposes. Feel free to adjust these names to suit your preferences.

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

Failure to trigger VS code extension functionality

After much thought, I've decided to embark on creating my own VS Code extension specifically for TypeScript/Angular code snippets. The first snippet I've developed is called Forloop.snippet: const ForLoopSnippet = 'for (let {{iterator}} = { ...

When importing a module, the function in the ts file may not be recognized or located

While attempting to create a VSTS (Azure Devops) Extension, I encountered a perplexing issue. Within my HTML page, I have a button element with an onclick listener: <!DOCTYPE html> <head> <script type="text/javascript"> VS ...

Encountering an issue with a Node native module not being found while attempting to import

Encountering an issue while working on a Svelte & TypeScript project where importing native Node modules is causing trouble. For instance, when typing: import { createInterface } from "readline"; in a .ts or .svelte file, a warning pops up saying: Plugin ...

Troubleshooting a GetStaticProps problem in Next.js

I'm currently facing an issue with retrieving posts from my WordPress site. After running tests on the URL endpoint, it seems to be functioning properly with client-side rendering. However, when I attempt to utilize the getStaticProps function, the re ...

Challenges Faced with Implementing Active Reports in Angular 9

After following all the necessary steps outlined in this website to integrate Active Reports with Angular 9 (), I encountered an error when trying to compile my app: ERROR in The target entry-point "@grapecity/activereports-angular" has missing dependen ...

Bring in numerous variables into a Gatsby component using TypeScript and GraphQL Typegen

import { graphql } from 'gatsby'; const Footer = ({phone}: { phone?: Queries.FooterFragment['phone'];}): JSX.Element => { return <footer>{phone}</footer>; }; export default Footer export const query = graphql` fragm ...

Accessing data from an API in Angular and logging it in the console instead of displaying it on a frontend table

The data retrieved from the API is not being displayed on the screen, but I can see it in the console log. Below is the .ts file: export class VisibilityComponent implements OnInit { check = false; pmDetails1: IEmployee[]; constructor( priv ...

I keep receiving multiple header errors from ExpressJS even though I am positive that I am only sending a single header

Can someone please help with the issue I'm facing in the code below: router.put("/:_id", async (req: Request, res: Response) => { try { // Create the updated artist variable const artist: IArtist = req.body; const updatedArt ...

Please ensure that the function chain has appropriate parameter and return types by specifying the tuple type

Can a new type be created for the given tuple/array that has certain validation constraints? The following array is considered valid: const funcs = [(a: string) => 1, (a: number) => 'A', (a: string) => 2] However, this one is invalid ...

The Disabled element does not exhibit effective styling

When we include the disabled attribute in the text element, the style does not work. Can you explain why? <input pInputText [style]="{'padding-bottom':'10px','padding-top':'10px','width':'100%&apos ...

The term 'ObjectId' is typically used as a type, but in this context it is being incorrectly used as a value

I've been scouring for an answer without success. As a newcomer to both stackoverflow and typescript, I've encountered an issue while creating a Mongoose Schema. Here's a snippet of my code: import { Schema, ObjectId } from 'mongoose&a ...

How can I enable dragging functionality for components (not elements) in angular?

While utilizing the Angular CDK drag and drop module, I have observed that it functions seamlessly on html elements like div, p, etc. However, when I apply a cdkDrag directive to a component, it does not seem to work as expected. <!-- IT WORKS --> ...

Create a NfcV Write Lock Block instruction

Seeking to make data on a NXP ICODE SLIX SL2S2002 tag type 5 (ISO 15693) read-only by utilizing the WRITE SINGLE BLOCKS command through the NfcV object in an app based on Ionic: private readonly cmdISO15693 = { READ_SINGLE_BLOCK: 0x20, WRITE_SI ...

Learn how to define an object with string keys and MUI SX prop types as values when typing in programming

I want to create a comprehensive collection of all MUI(v5) sx properties outside of the component. Here is an example: const styles = { // The way to declare this variable? sectionOne: { // What type should be assigned here for SXProps<Theme>? } ...

When using the subscribe method in Angular4, I am encountering a null value for the data

After receiving data from my subscription and displaying it, I encounter an issue when calling my function as it returns a "null" value. I apologize for any language errors in my message. Thank you. this.service.prepareNewVersion().subscribe(data2 => ...

How to add an item to an array in JavaScript without specifying a key

Is there a way to push an object into a JavaScript array without adding extra keys like 0, 1, 2, etc.? Currently, when I push my object into the array, it automatically adds these numeric keys. Below is the code snippet that I have tried: let newArr = []; ...

Conditionally typing in TypeScript to check if a string contains a specific value

Looking to create a function that takes a string as input and determines whether it contains '[]' or not. If it does, the function should return a list, otherwise an object. This is what I have so far: function customFunction<T = any>(input ...

Creating TypeScript types using GraphQL code generation: Generating types without any other code

Utilizing the typescript plugin for graphql code generator As documented This TypeScript plugin is fundamental and capable of creating typings from GraphQLSchema, which can be leveraged by other typescript plugins. It creates types for all aspects of you ...

How can you determine if a function is capable of throwing errors in TypeScript?

The announcement regarding the completion of `js-sys` project mentioned: We explored using TypeScript for the frontend, but opted against it because TypeScript does not specify whether functions throw exceptions. 1) Is this statement accurate? 2) If no ...

Encountering an error of ExpressionChangedAfterItHasBeenCheckedError while trying to refresh the

I'm encountering an issue that I need help with: https://i.stack.imgur.com/4M54x.png whenever I attempt to update the view using *ngIf to toggle on an icon display. This is what my .ts file looks like: @Component({ selector: 'app-orders&ap ...