Use bracket notation to verify if a property is undefined

Having some difficulty determining if the property value of an object is undefined when accessed dynamically with bracket notation. Here's a snippet of my code:

function toBritishDate(date: Date | string): string {
    console.log(date)
    return "foo"
}

function myFunc() {
    const project: { start_date?: string; end_date?: string } = {
        start_date: '2023-09-13',
        end_date: '2023-09-29',
    };

    const array: ("start_date" | "end_date")[] = ['start_date', 'end_date']
    array.forEach((element) => {        
        if (project[element] !== undefined) {
            console.log(toBritishDate(project[element]))
        }
   });
}

Feel free to check out the playground link.

Error encountered when calling toBritishDate on match.project[element]:

Argument of type 'string | undefined' is not assignable to parameter of type 'string | Date'. Type 'undefined' is not assignable to type 'string | Date'. (tsserver 2345)

It appears that

match.project[element] !== undefined
solely confirms if the property exists, without checking if the actual value is undefined. Any suggestions on how to confirm both the existence of the property and ensure it has a defined value?

Answer №1

This specific issue has been recognized as a missing feature, initially reported on microsoft/TypeScript#10530 and is currently being monitored at microsoft/TypeScript#56389. TypeScript does not track the identity of a key like element when indexing, such as project[element]. Instead, it focuses solely on the type, which in this case is the union type

"start_date" | "end_date"
. Consequently, your code is interpreted as:

declare const element1: "start_date" | "end_date";
declare const element2: "start_date" | "end_date";
if (project[element1] !== undefined) {
        console.log(toBritishDate(project[element2])) // resulting in an error
}

This approach is obviously unsafe. To distinguish between safe and unsafe code, TypeScript would need to have the ability to track the key's identity accurately, which it currently lacks.


Until this issue is resolved, a common workaround is to duplicate the property into a new variable to bypass the concerns related to indexing and identity:

    const projectElement = project[element];
    if (projectElement !== undefined) {
            console.log(toBritishDate(projectElement)) // behaves as expected
    }

By using projectElement as a single variable, the compiler can apply standard narrowing analysis effectively.

Link to Playground for testing code

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

Exploring the world of unit testing in aws-cdk using TypeScript

Being a newcomer to aws-cdk, I have recently put together a stack consisting of a kinesis firehose, elastic search, lambda, S3 bucket, and various roles as needed. Now, my next step is to test my code locally. While I found some sample codes, they did not ...

A guide on assigning a state variable to a dynamically generated component within a React application

I need to display user data from an array and have a button for each watchlist that deletes it. Although the backend is set up with a function deleteWatchlist, I am facing an issue in setting the state of the watchlistName for each watchlist after mapping ...

What is the reason for NextJS/React showing the message "You probably didn't export your component from the file where it was declared"?

What's the Issue The error code I am encountering Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the ...

JSReports encountered an unexpected token "<" in the JSON at position 0

Seeking assistance from those knowledgeable in JSReports, but open to suggestions from all... I've investigated the common issue of "unexpected token < in JSON at position 0", which typically arises when attempting to parse an HTML-formatted strin ...

What is the reason for the result of 0x80000000 & 0x80000000 being lower than 0?

What is the reason for this inconsistency in nodejs? 0x80000000 & 0x80000000 < 0 while 0x40000000 & 0x40000000 > 0 Also, if I were to use a larger hexadecimal number like 0x800000000, could it potentially introduce hidden bugs? POSTAG.t ...

Using jQuery to adjust the length of a string to fit within a specific width

I am working with a table and need to input strings in each cell, but they are wider than the cell width. I want to shorten the strings without breaking lines, and add '...' at the end to show that the string is long. The table consists of aroun ...

Having trouble accessing an injector service within the promise of a dynamically loaded JavaScript function that has been assigned to a global variable

Query I am facing an issue while trying to integrate PayPal with Angular. I am encountering difficulties when attempting to call an injected service inside a function of the promise returned. Any assistance in resolving this would be greatly appreciated. ...

Adjusting the input in a Textfield within React using Material UI

const [formData, setFormData] = useState({}); useEffect(() => { fetch("/formdata") .then((res) => res.json()) .then((data) => setFormData(data)); }, []); console.log("Form Data", formData); //Sorting by order let attr; ...

Can you explain the process of extracting images from JSON data using AJAX and jQuery?

Hello, I'm looking for guidance on incorporating jquery with AJAX to fetch images from a JSON file and showcase them on my website. Below is the code snippet I have put together. function bookSearch(){ var search = document.getElementById('sea ...

How can I send a value to an Angular element web component by clicking a button with JavaScript?

I want to update the value of an input in an Angular component by clicking on a button that is outside of the Angular Element. How can I achieve this in order to display the updated value in the UI? Sample HTML Code: <second-hello test="First Value"&g ...

What is the best method for storing a model in a database?

Hello, I am currently attempting to save a model to the database. I am simply inputting the value of a title in order to save it, as my id is set to auto increment. However, I have encountered an issue where my attempts have been unsuccessful. Can someone ...

Endless cycle of Facebook login prompts

Currently, I am utilizing the Facebook JavaScript SDK for a login button on my website. The functionality is working correctly, but there are two specific use cases where I seem to be encountering some issues. One issue arises when the Facebook cookie is ...

The act of employing `Function.prototype.run` within an Angular TypeScript class is deemed as illegitimate

Is there a way to globally define a new function called run within my Angular component as shown below? Function.prototype.run = function (delay: number) { // some content; }; However, the compiler shows an error that the Property 'run' does n ...

Transferring data from a child component to a parent component in Angular using @ViewChild requires providing 2 arguments

Currently, I am attempting to transmit data using @Output & EventEmitter and @ViewChild & AfterViewInit from a child component to a parent component. Below is the code from my parent component .html file: <app-child (filterEvent)=" getValu ...

Transforming the jQuery tooltip to be shown in a column layout

Hello, I am currently using the displayTag library to showcase some tables. My goal is to include a tooltip on each display:column element by utilizing jQuery. Below is the code snippet in question: <c:set var="titleName"><wp:i18n key="FILENAME" ...

Integrate SVG directly into the three.js module to eliminate the need for an additional HTTP request

Currently, I am developing a small website that features a simple 3D animation. The model is extruded from an SVG file loaded using SVGLoader. My goal is to enhance the loading speed by including the SVG as text in my threejs code, eliminating the need for ...

Tips for transferring a JavaScript variable to a Java servlet using the doPost method

I am working with an HTML table that contains dropdowns. When a user clicks on a dropdown, I store the column name and corresponding row (billdate) in a variable. Now, my goal is to pass this variable to my Java servlet's doPost method and then use it ...

What is the importance of maintaining immutability for objects in Redux?

What is the importance of immutability in Redux? While I understand that frameworks like Angular2 use onPush to leverage immutability for quicker rendering of views, I'm interested in learning about other reasons why Redux emphasizes immutability desp ...

Storing user and message data with LocalStorage technology

Seeking advice on a straightforward approach to storing user data and messages. My idea is to use unique key values, such as random tokens (Ynjk_nkjSNKJN) for users, and real ids (1,2,3) for messages. Has anyone encountered this issue before? The goal is ...

Problem with UV mapping when adjusting texture size

I am currently working on an application to modify minecraft models. To display the drawn texture mapped on the 3D player model, I am using ThreeJS. However, I'm facing a challenge related to changing the texture size. Initially, the texture is mappe ...