Employing an undeclared value as a property key within an object

I am using an object to associate one value with another, like so:

const wordToNumber = {
  one: 1,
  two: 2,
  three: 3,
}

However, I have a special case where if the user tries to retrieve a value by the key undefined, I want it to return 1.

To accommodate this, I modified the object to look like this:

const wordToNumber = {
  one: 1,
  two: 2,
  three: 3,
  [undefined]: 1,
}

This setup functions as expected when tested in a playground:

https://i.sstatic.net/36Yhl.png

However, TypeScript raises an error regarding the undefined key:

TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.

I'm questioning whether there is an issue with using undefined as an object key, or if it's acceptable and I can simply suppress the warning with ts-ignore?

Answer №1

Did you attempt to remove the square brackets? I found success with this method on JSFiddle.

const wordToNumber = {
    apple: 5,
    banana: 8,
    orange: 10,
    undefined: 1,
}

alert(wordToNumber["apple"])
alert(wordToNumber[undefined])

Answer №2

Have you considered utilizing a map in this scenario, possibly with the use of get and set methods?

const m = new Map();
m.set(undefined, "test");
console.log(m.get(undefined));

Answer №3

There are various methods to achieve this task. Personally, my approach would be as follows:

const convertWordToNumber = (word) => {    
    if (typeof word !== "string") {
        return "1";
    }
    
    return {
        apple: 1,
        banana: 2,
        cherry: 3,
    }[word];
}

convertWordToNumber("apple");

Instead of checking for undefined specifically, the function will simply return "1" if the input is not a string.

Answer №4

When it comes to JavaScript converting undefined into strings for object keys, there seems to be a safe aspect in this scenario. Ignoring the error might actually be acceptable. Here's an example situation:

enum LeftEnum {
    Required = 0,
    Hidden   = 1,
    Optional = 2
};

enum RightEnum {
    Required = 1,
    DontShow = 2,
    Optional = 3
};

type LeftObjectType = {
    Show?: LeftEnum
};

type RightObjectType = {
    Display: RightEnum
};

const convertLeftToRight = {
    [LeftEnum.Required]: RightEnum.Required as const,
    [LeftEnum.Hidden]:   RightEnum.DontShow as const,
    [LeftEnum.Optional]: RightEnum.Optional as const,
    undefined:           RightEnum.Optional as const
};

const lefts: LeftObjectType[] = [
    {},                      // undefined -> optional or 3
    {Show: LeftEnum.Hidden}, //         1 -> dontShow or 2
    {Show: LeftEnum.Required}, //       0 -> required or 1
    {Show: LeftEnum.Optional} // optional -> optional or 3
];

const newRight: RightObjectType[] = lefts.map(left => ({
    // Type 'undefined' cannot be used as an index type.(2538)
    Display: convertLeftToRight[left.Show]
}));

// produces correct results
console.log(newRight); 

// no error
const a: RightEnum.Optional = convertLeftToRight["undefined"];

// Type 'undefined' cannot be used as an index type.(2538)
const b: RightEnum.Optional = convertLeftToRight[undefined];

In this context, since we are confident that using undefined will not cause any issues and there is no possibility of confusion with "undefined", it may be reasonable to bypass the check.

However, I find the restriction on utilizing undefined for index types puzzling. TypeScript appears to recognize that using undefined as an object key works fine, as evident from including "undefined" leading to an error regarding multiple properties with the same name:

const convertLeftToRight= {
    [LeftEnum.Required]: RightEnum.Required as const,
    [LeftEnum.Hidden]: RightEnum.DontShow as const,
    [LeftEnum.Optional]: RightEnum.Optional as const,
    null: RightEnum.Optional as const,
    undefined: RightEnum.Optional as const,
    ["undefined"]: RightEnum.Optional as const,
    [undefined]: RightEnum.Optional as const,
    "undefined": RightEnum.Optional as const,
    "Undefined": RightEnum.DontShow as const
};

The object documentation highlighting the key as the blue keyword

undefined</code further adds to the confusion when compared to the green string <code>"Undefined"
or light green numbers.

https://i.sstatic.net/AwORw.png

Even if the string "undefined" is employed:

https://i.sstatic.net/1ASc7.png

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

Error encountered when attempting to pass a prop to styled-components in TypeScript

I'm struggling to resolve this TypeScript dilemma. ...message: 'Type '{ show: boolean; children: Element; }' is not compatible with type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<ThemedOuterStyledProps< ...

Using trackBy in conjunction with the async pipe

Attempting to utilize the async pipe along with *ngFor to exhibit an array of items obtained asynchronously. <ul> <li *ngFor="let item of items | async; trackBy: trackPost"> {{item.text}} </li> </ul> ngOnInit() { // a si ...

Using TypeScript absolute imports from another project for standard TypeScript files and declarations at a global scope

We are currently considering migrating a large JavaEE code base to TypeScript. Within this environment, there are multiple projects with intricate directory structures and JavaScript code that heavily relies on global variables across all projects. Althou ...

Issue: Multiplying values within an array in TypeScript requires that the left-hand side of the arithmetic operation must be of type 'any', 'number', or 'enum'

Having trouble with Typescript as I encounter this error message The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362) Specifically facing issues when trying to multi ...

In Angular 5, a variable's value becomes undefined once it is subscribed to outside of its assigned

I keep encountering an undefined value when trying to assign the subscribed value to a variable in my code snippet below. service.ts getIpAddress() : Observable<any> { return this.http .get(this.Geo_Api) .map((response: ...

Ways to refresh the information displayed on the view when the observable data is updated

I am using an observable called getContentfulEntry to retrieve data, while also passing data from another observable known as stateService. this.langSubscription = this.stateService.getLanguage() .subscribe(val => { this.lang = val; ...

Encountering a TypeScript type error when returning a promise from a function

I currently have a scenario in which there is a function that checks if user whitelisting is required. If not, it calls the allowUserToLogin function. If yes, it then checks if a specific user is whitelisted. If the user is not whitelisted, an error is thr ...

Require TypeScript interfaces to include all index types from a union

I have a union type defined as: type A = "a" | "b" | "c"; Now, I want to create an interface like this: interface B { [index: A]: string } However, I need this interface to include all options from the union type, resulting in the following interface ...

Migration unsuccessful due to incompatible peer dependencies detected - Updating Angular to Version 12 was not successful

Currently in the process of upgrading my Angular v11 apps to Angular v12. Encountering an error while attempting to upgrade Angular packages: ng update @angular/core@12 @angular/cli@12 Error: Migration failed due to incompatible peer dependencies The pa ...

Sending a POST request to an API with Angular and passing an object as the payload

I'm currently working on adding a feature to my app where I can take the products from an order and send them to the cart, essentially replicating the entire order. While I have successfully retrieved the order, I am facing difficulty in sending it b ...

The Viem Type Inference ABI has mysteriously vanished

I followed the documentation and online resources to migrate from Viem 0.8.x to 1.4.1, but I am facing difficulties making it work as intended. Here is the function I am trying to read from my ABI: { inputs: [], name: 'getTreasuryAndP ...

What is the best way to manage destroyed objects?

I've been working on a PIXI.js application and I'm faced with the challenge of managing resources to prevent memory leaks. To address this issue, I am utilizing the DisplayObject.destroy method. When a display object is destroyed, many of its in ...

Having trouble getting Typescript's Pick Array to work properly?

There seems to be an issue when using this line as an array, and I'm unsure how to resolve it: Pick<Author, PickedAuthorFields>[] </questionbody> I'm not sure why there is a problem if i use this line as array and how to fix it: ...

Troubleshooting a Custom Pipe Problem in Angular Material Drag and Drop

Currently, I am working on a project involving Angular Material Drag And Drop functionality. I have created a simplified example on StackBlitz which you can access through this link: here The project involves two lists - one containing pets and the other ...

Is it acceptable to include a @types library as a regular dependency in the package.json file of a Typescript library?

Should the library also be compatible with Typescript projects? I am developing a Typescript library that utilizes node-fetch and @types/node-fetch, which will be shared through an internal NPM registry within the company. If I only include @types/node-f ...

Error message in TypeScript React: Unable to assign onClick to type 'IntrinsicAttributes'

I recently came across this code for a component: Feedback.tsx import React, { useState } from 'react'; import './Feedback.css'; import FeedbackButton from './FeedbackButton'; function Feedback() { const [isOpen, setIsOpe ...

IntellJ Editor encounters Typescript error

Currently engaged in a project using Angular 1.6 and Typescript. Up until recently, there were no compilation errors to be found. However, I am now encountering some peculiar errors. The code remains unchanged and the application is functioning properly. ...

The offsetWidth of the nativeElement in Angular 2's ElementRef is consistently returning a value

Is there a way to retrieve the width of an element with a dynamic width using Angular 2? I can easily accomplish this with pure javascript, but not through Angular 2. constructor(private element: ElementRef) { // .... Obtaining the width let width = thi ...

The Angular component route is not refreshed, terminated, and reloaded

Encountered an issue with Angular 2+ related to loading a component, navigating to another route, and then reloading the component. The code below loads an array that is then displayed using ngFor. this.sub = this.subjectsService.getAllSubjects().subscri ...

Utilizing feature flags for Angular modules to enable lazy loading

Can we dynamically change the lazy loaded module based on a specific flag? For instance, loading module A if the flag is active and module B otherwise. The crucial aspect is that both modules should use the same path. Approach #1 - dynamic loadChildren() ...