Can a type error be triggered if a map already contains a specific argument?

I am currently working on a class that includes a protected map holding various values, along with a method to add new entries to this map.


class DataStorage {
  protected readonly dataValues: Map<PropertyKey, number> = new Map();
  
  public updateData(key: PropertyKey, value: number): void {
    if (this.dataValues.has(key)) {
      throw new Error('key already exists');
    } else {
      this.dataValues.set(key, value);
    } 
  }
}

Is there a way to set up types for this class and method so that if a key is added which already exists in the map, it would trigger a type error during compilation rather than throwing an error at runtime? I know it's possible to handle this with an Error message, but I'm curious about achieving this check using TypeScript compiler.

const storage = new DataStorage();
storage.updateData('apple', 4); // valid
storage.updateData('banana', 5); // valid
storage.updateData('apple', 6); // invalid - 'apple' already exists!

Answer №1

class UniqueContainer<T extends Key = never> {
  protected readonly items: Map<T, number> = new Map();

  public addItem<U extends Key>(key: Exclude<U, T>, value: number) {
    if (this.items.has(key as any as T)) {
      throw new Error('This key already exists');
    } else {
      this.items.set(key as any as T, value);
    }
    return this as UniqueContainer<T | U>
  }
}

let uniqueContainer = new UniqueContainer()
  .addItem('apple', 1) // valid
  .addItem('banana', 2) // valid
  .addItem('apple', 3) // invalid - apple key already exists!

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

Broaden the attributes of an existing function

I am currently developing a Koa web server and I am exploring if it's feasible to include an additional parameter to an already established method on the Koa.app object. const mongoState = await connectToDatabase(); app.use(async (ctx, next) => ...

The specified property 'nodeName' is not recognized within the data type 'EventTarget'

In the code snippet below, we are checking whether the user is interacting with an input field, textarea, or contenteditable element. If any of these conditions are met, we should clear out the keys array and stop the script execution. let keys: any[] = [] ...

The typings for object properties in Typescript

I recently encountered a function call in my code: var myVar = myFunction({ property: 'prop', functionProperty() { console.log(this.property); }, functionProperty2() { this.functionProperty(); } }); I' ...

Issue connecting database with error when combining TypeORM with Next.js

I am attempting to use TypeORM with the next.js framework. Here is my connection setup: const create = () => { // @ts-ignore return createConnection({ ...config }); }; export const getDatabaseConnection = async () => { conso ...

Is it possible to access a class with protected/private fields written in TypeScript from outside the class in JavaScript?

Currently, I am delving into TypeScript classes (though my experience with OOP is limited). The following code snippet is extracted from the chapter on classes in https://www.typescriptlang.org/docs/handbook/classes.html Here's the issue at hand: I ...

Angular Material Popup - Interactive Map from AGM

I am in the process of developing a material dialog to collect user location information using AGM (angular google maps). I have successfully implemented a map on my main page, but when the dialog is opened, it only shows a blank space instead of the map. ...

What is the best way to fetch the id of the option that has been chosen from a bootstrap drop-down menu?

I recently created a basic drop-down list like this: https://i.sstatic.net/4Tlxx.png Here is the HTML code for it: <select class="form-control" id='0' (change)="retrieveValue($event.target)"> <option id='0'>{{ g ...

Retrieving the HTTP Error Response Body in Angular using HttpInterceptor

I am currently working on implementing an HttpInterceptor in Angular to catch errors and display them in a modal. In addition to error code and message, I want to include the body of the response for a more detailed description of the error (such as in the ...

What are the steps to transpile NextJS to es5?

Is it possible to create a nextjs app using es5? I specifically require the exported static javascript to be in es5 to accommodate a device that only supports that version. I attempted using a babel polyfill, but after running es-check on the _app file, ...

Angular: efficient exchange of information among components

I have a component X that handles a WebSocket. And within component X, I also have multiple presentation components (e.g. Y). Whenever the WebSocket receives a specific message, I need to perform an action in a particular component (e.g. refresh data). To ...

Caution: Updating a component is not possible during the rendering of another component. ReactJS

I am encountering an error in my ReactHooks/Typescript application with a Navigation component that renders a PatientInfo component. The PatientInfo component is conditionally rendered based on the props it receives, determined by a searchbox in another ch ...

I'm struggling to include a link in my project card component - I've tried using both the Link tag and anchor tag, but so far, I haven't been successful in

I am having trouble getting the link tag to work properly in my UI. I have tried using both the link and anchor tags, but neither seems to be functioning as expected. Can someone please advise on how to fix this issue? https://i.sstatic.net/tAD7C.png I w ...

Generate sample data within a fixture

Currently, I am in the process of working on a project that involves creating users and conducting tests on those users. To generate user data such as first name and last name, I am utilizing the faker tool. My goal is to create a user with these generated ...

Exploring Observable Functionality in Angular 6

I've been grappling with understanding Angular Observables, but I've managed to get it working. My goal is to fetch data for my dynamic navigation bar. I successfully verified whether the user is logged in or not and displayed the Login or Logout ...

Storing an array of objects in local storage is not working in Angular 9

I've encountered an issue trying to save an array of JSON objects into local storage, and I'm puzzled as to why it's not functioning correctly. Despite utilizing localStorage.setItem('comparisons', JSON.stringify(setComparisons)), ...

Displaying components sequentially in Angular 12 one after the other

I am looking to showcase a set of words from an array using the card component. Is there a way to display only one card at a time and cycle through them by clicking? (I want each card to contain its own unique word, rather than just changing the text in a ...

Error encountered: firebase is not defined within a Kotlin/JS project utilizing Dukat generated declarations

As part of my kotlin js project, I brought in the firebase dependency. Leveraging Dukat, I obtained access to the type references and successfully compiled them. While my Kotlin code compiles without any issues, it appears that the webpack bundle does not ...

Transfer a file using fetch (POST request) within a TypeScript React component

i am trying to send a file to an api using fetch. this is the api: and here is how it wants to be handled: You can perform Ogre transformations directly by making a HTTP POST request: Convert to GeoJSON http://ogre.adc4gis.com/convert with the following ...

Struggling with extracting an array of objects from a JSON file and accessing individual attributes within each object?

As a newcomer to Typescript, I am eager to work with JSON and access its objects and attributes. However, I am encountering difficulties in achieving this. I have attempted using functions like 'for of' and 'for in', but unfortunately, ...

Error encountered: Type 'IPromise<{}>' is not compatible with type 'IPromise<IWebErrors[]>'. This issue arose during the migration from Typescript version 1.8 to 2.5

Can someone please help me troubleshoot this code? I've tried adding .topromise() and using a then, but it's not solving the issue. getWebErrors(): ng.IPromise<Array<IWebErrors>> { var defer = this.q.defer(); this.h ...