Make sure all scenarios are accounted for in TypeScript union type switching

I have a union type defined as follows:

type Action  = 'foo' | 'bar' | 'baz';

I would like the compiler to throw an error if someone attempts to extend this type.

Consider the code snippet below:

type Action = 'foo' | 'bar' | 'baz';

function create(action: Action) {
    let something;
    switch (action) {
        case 'foo':
            something = action.toLowerCase();
            break;
        case 'bar':
            something = action.toUpperCase();
            break;
    }

    return something;
}

In this example, the baz case is not handled, yet TypeScript does not raise any errors. Is there a way to enforce this and make TypeScript flag such cases where types are extended without handling all possible options?

playground: here

Answer №1

If you declare a return type for the function, TypeScript will alert you if you're not addressing a specific scenario where there is a chance of returning an undefined value due to the unhandled case.

To illustrate this, experiment with the following code in your sandbox:

type Action = 'foo' | 'bar' | 'baz';

function create(action: Action): string {
    let something;
    switch (action) {
        case 'foo':
            something = action.toLowerCase();
            break;
        case 'bar':
            something = action.toUpperCase();
            break;
    }

    return something;
}

You will encounter the error below in your return statement:

Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.(2322)

To resolve this, simply add a case to handle baz and the compilation error will disappear.

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

What is the best way to find the common keys among elements in a tuple type?

type Tuple=[{a:string,x:string,z:string},{b:string,x:string,z:string}] type IntersectionOfTupleElementKeys<T>=... type MyType = IntersectionOfTupleElementKeys<Tuple> // = ('a'|'x'|'z')&('b'|'x&ap ...

Struggling with incorporating GlobalStyles in the app.tsx file

I have been working with next13 and styled-components. Initially, everything seemed fine in my file globalStyles.ts, and all was functioning perfectly. However, I started encountering errors related to the import of <GlobalStyles/>. Specifically, th ...

Discover the process of changing a prop with a button click in NextJS

In my NextJs project, I have a video player component that displays videos using a {videoLink} prop: <ReactPlayer playing={true} controls={true} muted={true} loop={true} width="100" height="100" url={videoLinkDeep} poster="ima ...

No bugs appeared in Next.js

I am currently in the process of migrating a large create-react-app project to NextJS. To do this, I started a new Next project using create-next-app and am transferring all the files over manually. The main part of my page requires client-side rendering f ...

Input values that are true, or in other words, fulfill conditions for truthiness

Is there a specific data type in TypeScript to represent truthy values? Here's the method I'm working with: Object.keys(lck.lockholders).length; enqueue(k: any, obj?: any): void It seems like TypeScript allows checking for empty strings &ap ...

Error: Property 'content' is not defined and cannot be read

I encountered an issue with a config file while attempting to build with AOT using the command ionic cordova build android --prod Error: ./src/config/.env.ts Module build failed: TypeError: Cannot read property 'content' of undefined at Object ...

Updating the mat-icon in a row when a button is clicked

I am currently working on implementing the mat-table in my project. I am facing an issue where I need to change the mat-icon of a button based on a click event, but I only want this change to apply to a single row in the table. At the moment, I am able to ...

Avoid printing employees whose ID begins with special characters

My C# API sends all employee information from the database to my Angular web app. I need to filter out employees with IDs starting with '#' in Angular. Employee = Collaborator Below is the Angular service code that calls the API to fetch the d ...

Limit an object to only contain interface properties

Suppose we have the following object: o {a : 1, b : 2} and this interface defined as: interface MyInterface { a : number } We are now looking to create a new object that represents the "intersection" of o and the MyInterface: o2 : {a : 1} The mai ...

Why is Typescript unable to recognize the name '$' even after importing jquery?

Currently, I am utilizing TypeScript version 1.4.1 for a project setup like this: scripts/ libs/ jquery/ jquery.d.ts // Latest from DefinitelyTyped jquery.js // 2.1.3 lodash/ lodash.d.ts // Latest fr ...

Is it possible to deduce the output type of a function based on its input?

In a web development project, the function getFormData() plays a crucial role in validating and sanitising a FormData object based on a specified schema. If the validation process goes smoothly without any errors, the function will return the cleansed Form ...

tying [inactive] to a specific attribute

I have successfully implemented the functionality to disable the button when the email is in the correct format, as shown in my code below. Now, I am looking to implement the following scenario: The Get Started button should be disabled by default If a u ...

The Network plugin is having issues with the PWA application in Ionic 4

I've been utilizing the network plugin successfully on native/Cordova devices. However, I have encountered an issue when trying to use it on a PWA app (specifically when there is no wifi connection). Can anyone shed light on why this might be happenin ...

Using async/await with mysql2 in Node.js can lead to undefined rows and fields

I am facing an issue where the query below is returning undefined in rows and field even though the user table has data. How can I properly use the promise version in TypeScript? Any help would be greatly appreciated. Thank you... code import mysql from ...

Strategies for handling HTML content in the getProduct API call using Angular resolve

Components and Services Setup export class ProductComponent implements OnInit { constructor( private route: ActivatedRoute, private router: Router, ) { } ngOnInit() { this.route.data .subscrib ...

Give it a little time before uploading a widget onto the page

As a newcomer to programming, I recently came across this code from an open source project. I am in the process of loading a widget onto a website. Instead of having the widget load instantly, I would like it to wait 10 seconds before displaying. Below i ...

how to verify if a variable exists in TypeScript

Is there a recommended method for verifying if a variable has a value in TypeScript 4.2? My variable may contain a boolean value. I'm thinking that using if(v){} won't suffice as the condition could be disregarded if it's set to false. ...

(angular 8) Error occurred when converting a file or image to FormData due to an invalid value (Note: FormData object printed as Object Form{})

I encountered an issue where I am getting an invalid value from form data. The value appears correct in `this.fileData` with a size of 5701, but becomes empty when converted to form data - `{}` is logged when I console.log the form data. Additionally, acce ...

Discovering routes in Angular2

I'm attempting to replicate something similar to this example here: AngularJS show div based on url/condition <span id="page-locator" *ngIf="location.path() == '/overview'">test</span> Unfortunately, it's not working as ex ...

When configuring Gatsby with Typescript, you may encounter the error message: "You cannot utilize JSX unless the '--jsx' flag is provided."

I am currently working on a Gatsby project and decided to implement Typescript into it. However, I encountered an error in my TSX files which reads: Cannot use JSX unless the '--jsx' flag is provided. What have I tried? I consulted the docume ...