What is the proper way to specify type hints for a Map with keys being classes and values being instances of those classes?

I possess a map where the keys represent different classes and their corresponding values are instances of those classes.

// JavaScript code
class A {};
class B {};

const map = new Map();

map.set(A, new A);
map.set(B, new B);

What would be the correct way to type-hint this map in TypeScript?

Answer №1

To create a customized map definition, you'll need to deviate from the standard one which requires keys and values to be of the same type without any relation setup between them.

Here's an example of how you can do it:

type Constructor = new (...args: any) => any;

interface ConstructorMap {
    clear(): void;
    delete(key: Constructor): boolean;
    get<K extends Constructor>(key: K): InstanceType<K> | undefined;
    has(key: Constructor): boolean;
    set<K extends Constructor>(key: K, value: InstanceType<K>): this;
    readonly size: number;
}

class A { a = '' };
class B { b = 1 };

const map: ConstructorMap = new Map();

map.set(A, new A);
map.set(B, new B);

const a = map.get(A); // A | undefined

// This will result in an error: Argument of type 'B' is not assignable to parameter of type 'A'.
map.set(A, new B);

Playground

Check out the documentation on the InstanceType<Type> utility for more information.

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

Tips for incorporating conditional types into function parameters based on existing input

The title might be confusing, so allow me to clarify. My Objective I am referring to the code snippet below. I aim to specify the route property based on the types property as either a string or a function that returns a string. The Code Let's b ...

initiating nest start removes the json files in the dist directory

As I work on my nestjs application, I find myself needing to ensure that specific json files are copied to the dist directory. This is especially important for the "engines" folder, where the json files in src/engines must be replicated in dist/and prod. ...

The use of async/await within an observable function

I am looking to establish an observable that can send values to my observers. The issue lies in the fact that these values are acquired through a method that returns a promise. Is it possible to use await within the observable for the promise-returning f ...

Is there a way to identify when a user is returning to a previous page in Angular2

How can I detect if a user has pressed the back button in their browser to navigate back while using Angular? Currently, I am subscribing to router events to achieve this. constructor(private router: Router, private activatedRoute: ActivatedRoute) { ...

Tips for implementing react-select types in custom component development

Currently, I'm in the process of developing custom components for DropdownIndicator to be used on react-select with Typescript. However, I am encountering difficulties with the component's type due to my limited experience with Typescript. I wou ...

Having constant problems with ngModel twoway binding. Any suggestions on how to successfully bind to a property in order to update an api link?

I am attempting to implement two-way binding in order to dynamically change the API endpoint when a button is clicked. The value attribute of the button should be used as part of the API URL string. I tried following an example in the Hero Angular App, bu ...

IntelliJ IDEA does not support the recognition of HTML tags and directives

I seem to have lost the ability to switch between my HTML and TS files in Intellij IDEA; the tags, directives, and autocompletion in HTML are no longer working. Additionally, I'm receiving some warnings: https://i.stack.imgur.com/QjmNk.png Is there ...

Unique Version: When utilizing custom window.FileReader methods, Angular zone execution is bypass

Upon transitioning an Ionic/Angular project from Cordova to Capacitor, I found it necessary to override the default window.FileReader in order to successfully execute the onload() method. Here is the approach I took (https://github.com/ionic-team/capacitor ...

Utilizing Angular 2 for a dynamic Google Map experience with numerous markers

I am currently working on an Angular2 project that involves integrating Google Maps. My goal is to display multiple markers around a specific area on the map. Although I have been able to get the map running, I am facing issues with displaying the markers ...

A guide on incorporating Union Types in TypeScript

Currently utilizing typescript in a particular project where union types are necessary. However, encountering perplexing error messages that I am unsure how to resolve. Take into consideration the type definition below: type body = { [_: string]: | & ...

Having trouble importing a tailwind CSS file into a Remix.js project without TypeScript throwing an error

https://i.sstatic.net/pvyUf.png I've attempted to implement the solution found here but unfortunately, it's still not working for me. Below are my configuration files: remix.config.ts: /** @type {import('@remix-run/dev').AppConfig} * ...

What is the best way to access and utilize an id within an angular component's routing system?

I am currently working on an Angular application, and this is my first experience with JS. I have a main view where I display several elements, such as movies, each of which is clickable and links to a detailed view of the movie. My question is how can I h ...

I am having trouble indexing my object in React/Redux. I keep getting a TypeError that says I cannot read property '1' of undefined

Currently, I'm working on a personal project focused on creating a meal planner table using React/Redux for app development and state management. While nearing completion, I've encountered a perplexing issue. The problem arises when trying to ite ...

What is the best way to selectively pass certain values to the args object?

Is there a way in TypeScript to pass only one argument into args and have other values be default without using "args = {}" or declaring defaults within the function to avoid issues with intellisense? function generateBrickPattern ( wallWidth: number, ...

What is the key to ensuring the content in your canvas adapts to different screen sizes

Greetings! I wanted to extract the values from this specific meta tag: <meta name="viewport" property="viewport" content="width-device-width, initial-scale=1"> To retrieve content from a meta tag using JavaScript, I used the following code snippet: ...

TypeScript versions 2.3 and 2.4 experiencing issues with generic overloads

After upgrading from typescript 2.2, I encountered an issue with the following example. interface ILayoutResult { id: string; data: any; } interface ILayout{ getResult<T extends ILayoutResult | ILayoutResult[] | void>() :T; } class te ...

Ways to determine the current active tab in React are:

Currently, I am facing an issue with my code involving two tabs. Upon clicking on the second tab, I want to display a specific message. However, I am struggling to determine when the second tab is selected. The main problem lies in the fact that the selec ...

Determine the data types present in an array using TypeScript

It appears that Typescript has a strong compatibility with AST. When checking x.type == "Abc", Typescript is able to infer that x is of type Abc. This capability comes in handy when I use it for typechecking JS files with JSDOC format annotations, and I be ...

Expandable Grid Sections in React MUI

Is there a way to create a grid layout where items with showDefault: true are always displayed at the top, and then users can click an arrow button to expand the grid and also show the items with showDefault: false? Any suggestions on how to achieve this? ...

Creating a return type in Typescript Generics depending on the provided argument

Could you assist in creating a dynamic TypeScript return type based on whether an argument is undefined or not? Here is a export interface ToObject<T> { [k: string]: T; } export const toObject = <T, V = (keyof T)>( list: T[], key: keyof ...