Using "undefined" as the discriminator in a discriminated union

My idea is to implement a discriminated union using null as the discriminator:

type Result<T> = { result: T; error: null } | { result: null; error: string }

If the function register() returns a Result, I could handle it like this:

const { error, result: user } = await register(fields)
if (error) return typedjson({ fields, fieldErrors: { email: error } })
// All good: user data is accessible

However, TypeScript doesn't appear to be recognizing null as a discriminator for the union: https://i.sstatic.net/DlRXl.png

This is puzzling considering that https://github.com/microsoft/TypeScript/pull/27695 indicates that null should work as a discriminator.

My temporary solution:

Utilize boolean as the discriminator instead:

type Result<T> = { invalid: false; result: T; error: null } | { invalid: true; result: null; error: string }

Nevertheless, this introduces an extra (superfluous) variable in the destructuring statement:

const { invalid, error, result: user } = await register(fields)
if (invalid) return typedjson({ fields, fieldErrors: { email: error } })

Answer №1

Your code may not provide the expected result due to the fact that an empty string is considered falsy in JavaScript.

To handle this, you can use if (error === null) ... to differentiate the union of values.

For a hands-on demonstration, you can visit this Playground

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

Button for saving content located in expo-router header

I am a beginner in react native and I am attempting to connect a save button in a modal header using expo-router. I have managed to make the button work within the modal itself, but I would like it to be located in the header set by expo-router. It doesn&a ...

The string variable in the parent app is resetting to empty after being populated by the service call

I am facing an issue with my app components where AppComponent acts as the parent and ConfigComponent as the child. In the constructor of AppComponent, a service call is made to set a variable but I encounter unexpected behavior when trying to access this ...

What is the best way to update a BehaviorSubject holding an array without replacing the entire array?

When it comes to adding items to an array BehaviorSubject, the common practice is to assign a copy of the entire array along with the new item using next(). However, I am looking for a way to push items into this array without having to assign a full copy ...

How can I fetch a file using a JavaScript function in Pug/Angular?

Within the Angular7/Pug application, there was previously a file download link implemented in table.component.pug like this: div p File to download: a([href]="downloadLink", download="table.xlsx") some-icon span some-text Now, I a ...

Keep going in the for await loop in NodeJS

My code snippet looks like this: for await (const ele of offCycles) { if ((await MlQueueModel.find({ uuid: ele.uuid })).length !== 0) { continue; } <do something> } I'm curious if it's possible to use a continue st ...

Why is @faker-js/faker not usable in a TypeScript project, showing undefined error, while the older "faker" import still functions correctly?

Currently, my packages.json file includes: "faker": "^5.5.3", "@types/faker": "^5.5.3", I am sticking with version 5.5.3 due to another project dependency (codecept) that requires this specific version. The ...

What is the best way to retrieve the previous URL in Angular after the current URL has been refreshed or changed

Imagine being on the current URL of http://localhost:4200/#/transactions/overview/5?tab=2 and then navigating to http://localhost:4200/#/deals/detail/ If I refresh the deals/detail page, I want to return to the previous URL which could be something like h ...

What could be causing the TypeScript exhaustive switch check to malfunction?

How come the default case in the switch statement below does not result in an exhaustive check where 'item' is correctly identified as of type 'never'? enum Type { First, Second } interface ObjectWithType { type: Type; } c ...

Saving large amounts of data in bulk to PostgreSQL using TypeORM

I am looking to perform a bulk insert/update using TypeORM The Test entity is defined below: export class Test { @PrimaryColumn('integer') id: number; @Column('varchar', { length: 255 }) testName: string; } I have the f ...

How to refresh a specific component or page in Angular without causing the entire page to reload

Is there a way to make the selected file visible without having to reload the entire page? I want to find a cleaner method for displaying the uploaded document. public onFileSelected(event): void { console.log(this.fileId) const file = event.targe ...

Accessing the constants and state of child components within a parent component in React

I've created a MUI TAB component that looks like this <Box sx={{ width: "100%" }}> <Box sx={{ borderBottom: 1, borderColor: "divider" }}> <Tabs value={value} onChange={handleChange} aria-label ...

React Typescript is causing issues with the paths not functioning properly

Looking to simplify my import paths and remove the need for deeply nested paths. Currently working with React and TypeScript, I made adjustments to my tsConfig file like so: { "compilerOptions": { "baseUrl": "src", & ...

Typescript: The dilemma of losing the reference to 'this'

My objective is to set a value for myImage, but the js target file does not contain myImage which leads to an error. How can I maintain the scope of this within typescript classes? I want to load an image with the Jimp library and then have a reference to ...

The type 'ssr' is not found within the 'ResourcesConfig | LegacyConfig | AmplifyOutputs' interface. Error code: ts(2353)

I've been following a step-by-step tutorial (check it out here at 2:25:16) on creating a full stack application, but I've hit a roadblock when trying to enable SSR. import "@/styles/globals.css"; import type { AppProps } from "next ...

Importing images in Typescript is a simple and effective

I came across a helpful solution at this Stackoverflow thread However, I encountered an error: [ts] Types of property 'src' are incompatible. Type 'typeof import("*.png")' is not assignable to type 'string | undefined& ...

Can a single shield protect every part of an Angular application?

I have configured my application in a way where most components are protected, but the main page "/" is still accessible to users. I am looking for a solution that would automatically redirect unauthenticated users to "/login" without having to make every ...

Jest is raising a TypeError: Unable to access attributes of an object that is undefined (referencing 'getVideoTracks')

When running my unit tests with Jest, I encountered an error: TypeError: Cannot read properties of undefined (reading 'getVideoTracks') Does anyone have any suggestions on how to properly test the following line using Jest? [videoTrack] = (await ...

Here's a revised version: "How to link a lambda layer with a function in a serverless.ts file using the

When working with the serverless framework using the typescript template, a serverless.ts file is generated. I am currently integrating lambda layers with existing functions and encountering a typescript error. The error message reads: "Type '{ Ref: ...

What steps should I take to successfully deploy my Vite-React and Typescript application on Heroku?

I'm having difficulty deploying my front-end Vite application to Heroku because it seems to be searching for a start script, which Vite doesn't have. Here are the logs I am seeing: 2022-08-23T23:34:35.000000+00:00 app[api]: Build succeeded 2022- ...

SystemJS could not locate the root directory for RxJS

There seems to be an issue with SystemJS loading rxjs modules on Windows, as it throws a 404 Not Found error on the rxjs directory. This problem does not occur on OSX, and all modules are up to date. GET http://localhost:8080/node_modules/rxjs/ 404 (Not F ...