Is it possible for TypeScript to define keys that are permitted to be absent but not able to be assigned the value of `undefined`?

Query Synopsis

My aim is to restrict explicit values of undefined while permitting implicit undefined values.

Context

In the realm of JavaScript, there exists a scenario where attempting to access a nonexistent key results in undefined, similarly, accessing an existing key may also yield undefined.

For instance,

  1. [1, 2, undefined, 4][2] -> undefined
  2. [1, 2, 3, 4][99] -> undefined
  3. {a: 1, b: undefined}.b -> undefined
  4. {a: 1, b: 2}.foo -> undefined.

The first and third examples explicitly access undefined values, whereas the second and fourth examples implicitly access undefined values.

Query Statement

The task at hand is to designate a key that may or may not be present (optional), with the condition that if it does exist, it cannot be undefined. Is this feasible?

Additional Context

// - mustExistAndCouldBeUndefined must be present in this type, but it may be undefined.
// - couldExistAndCouldBeUndefined may be present in this type. If present, it can be undefined. If absent, it's undefined.
// - couldExistButCannotBeUndefinedIfItDoes may be present in this type. If present, it cannot be undefined. If absent, it's undefined.
type Example = {
    mustExistAndCouldBeUndefined: number | undefined;
    couldExistAndCouldBeUndefined?: number;
    ??? couldExistButCannotBeUndefinedIfItDoes ???
};

// I want this to be allowed, since couldExistButCannotBeUndefinedIfItDoes is permitted to be absent (implicitly undefined).
const a: Example = {
    mustExistAndCouldBeUndefined: undefined,
};

// I want this to be DISALLOWED as couldExistButCannotBeUndefinedIfItDoes is not permitted to exist and be undefined (explicitly undefined).
const b: Example = {
    mustExistAndCouldBeUndefined: undefined,
    couldExistButCannotBeUndefinedIfItDoes: undefined,
};

Is there a way to implement a concept similar to

couldExistButCannotBeUndefinedIfItDoes
as seen in the code snippet above?

Answer №1

To distinguish between undefined and optional values, you can activate the Typescript rule called exactOptionalPropertyTypes (Documentation) in your tsconfig.json file.

Without this rule:

type TypeForTest = {
  optionalAndUndefined?: string;
}

With this setup, the property optionalAndUndefined will default to undefined if it is not defined explicitly.

For example, you can do the following:

const x: TypeForTest = {}
// OR
const x: TypeForTest = {
  optionalAndUndefined: undefined;
}

Once the rule is activated, only this will be valid:

const x: TypeForTest = {}

However, the following will now be prohibited:

const x: TypeForTest = {
  optionalAndUndefined: undefined;
}

On the flip side, if your type is defined as:

type TypeForTest = {
  optionalAndUndefined: string | undefined;
}

you can now do this:

const x: TypeForTest = {}

and this is also acceptable:

const x: TypeForTest = {
   optionalAndUndefined: undefined;
}

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

Access file using operating system's pre-installed application

How can I open a file using the default application for that file type on different operating systems? For example, when opening an image.png on Mac, it should open with Preview, and on Windows with Windows Photo Viewer. I know you can use open image.png ...

`Property cannot be redefined: __internal__deprecationWarning` detected in a Shopify Hydrogen development project

Recently, while working on my Shopify Hydrogen project using Remix and Typescript, I encountered a sudden error when running npm run dev. Everything was functioning perfectly just 5 hours ago, but after returning from dinner, the app refuses to launch. ╭ ...

Combining results from multiple subscriptions in RxJS leads to a TypeScript compiler error

I am utilizing an Angular service that provides a filterObservable. To combine multiple calls, I am using Rx.Observable.zip(). Although it functions as expected, my TypeScript compiler is throwing an error for the method: error TS2346: Supplied paramete ...

What is the best way to transfer information from one column to another column with Office Scripts?

I'm in the process of automation with Microsoft Excel using Office Scripts, and I've hit a roadblock when trying to transfer data from one column to another. https://i.sstatic.net/56ipi.png Specifically, I need to move the data from the Date co ...

Encountering an Angular 13 ChunkLoadError during application deployment, despite the presence of the respective chunk

We encountered an issue with our application's upgrade from Angular 11 to 13. While running 'ng serve' on the local machine works fine, deploying it to our Azure app service causes the lazy loaded modules to fail loading. The specific error ...

Prevent selection of future dates in Kendo UI Calendar Widget

Can someone please advise on a method to disable future dates (i.e., gray them out) in the Kendo UI Calendar widget? I've attempted hiding the future dates, but it doesn't look good. I've also tried different ways to gray them out without su ...

TS Mapped Type: Dynamically exclude specific keys based on their values

Seeking a method to create a mapped type that excludes specific keys based on the value of the mapped key. For instance: Consider an option: Options struct, where Options is a union type defined as: { type: DataType } or { type: DataType, params: DataPar ...

Mastering the art of constraining TypeScript function parameters using interface properties

Hey there, I've been exploring ways to restrict a function parameter so that it only accepts "strings" related to interface properties, similar to what I achieved in the validate fields function: Please note: The TypeScript code provided here is simp ...

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>? } ...

What is the process of converting the new syntax of SomeFunction() to TypeScript?

When I try to convert a basic JS file to TS while having implicit "any" disabled, I encounter the following error: Error TS7009: When attempting to create a new expression without a constructor signature, it implicitly defaults to an 'any' typ ...

Disable the functionality of the device's back button to prevent it from going back to the

For my project, I utilize popups to display important information to the user. When a popup is displayed, how can I override the functionality of the device's back button so that instead of navigating to the previous route, it will close the popup? ...

Angular TextInput Components don't seem to function properly when dealing with arrays

I am trying to create a collection of text input components with values stored in an array. However, when using the following code, the values seem to be placed incorrectly in the array and I cannot identify the bug. <table> <tr *ngFor="let opt ...

What is the process for upgrading TypeScript to the latest version?

Is there a way to upgrade TypeScript version for ASP.net MV5 project in Visual Studio 2015? I attempted searching through Nuget but couldn't locate it. There seems to be an issue with the razor intellisense (index.d.ts file) and I'm hoping that ...

Tips for managing open and closed components within a React accordion and ensuring only the clicked component is opened

Unique Accordion component: const CustomAccordion = (props: AccordionProps) => { const { label, levels, activeId, id } = props const [isExpand, setIsExpand] = useState(false) const onPress = useEvent(() => { setIsExpand( ...

Dealing with various node types in a parse tree using TypeScript: Tips and Tricks

I am in the process of converting my lexer and parser to TypeScript. You can find the current JavaScript-only code here. To simplify, I have created an example pseudocode: type X = { type: string } type A = X & { list: Array<A | B | C> } ty ...

Issues with implementing AddEventListener in InAppBrowser on IONIC 2

I am currently working on implementing AddeventListener to listen for 'Exit' and 'LoadStart' events in InAppBrowser within IONIC2. Here is my HTML: <button (click)="browsersystem('https://www.google.com')" > Visit URL& ...

Using Jasmine to simulate an if/else statement in Angular/Typescript unit testing

After making a minor change to an existing function, it has been flagged as new code during our quality checks. This means I need to create a unit test specifically for the new 4 lines of code. The challenge is that there was never a unit test in place for ...

What is the proper way to utilize a class with conditional export within the Angular app.module?

This query marks the initiation of the narrative for those seeking a deeper understanding. In an attempt to incorporate this class into app.module: import { Injectable } from '@angular/core'; import { KeycloakService } from 'keycloak-angul ...

What could be preventing me from setting a boolean variable within an Observable?

After retrieving data from the Service, I am attempting to hide a specific div element. Below is the HTML code: <progressbar *ngIf="isLoadingBootStockData" [value]="100" type="default"> </progressba ...

Developing a specialized command-line application for currency conversion is my current project

Currently, I am working on developing a command-line application for currency exchange. I have created an interface to define the structure of an object array that will store the keys and values of currency names along with their current values in the inte ...