Making sure a value is a specific string in TypeScript

Here is what I currently have:

type AppDisplay = "MainMenu" | "Game" | "GameOver";

interface AppState {
  appDisplay: AppDisplay
}

const initialAppState : AppState = {
  appDisplay: "MainMenu"
}

type ActionType = {
  type: "DisplayMenu" | "DisplayGame" | "DisplayGameOver";
}

const appStateReducer = (state : AppState, action : ActionType) => {
  switch (action.type) {
    case "DisplayMenu":
      return {
        appDisplay: "MainMenu"
      }
    case "DisplayGame":
      return {
        appDisplay: "Game"
      }
    case "DisplayGameOver":
      return {
        appDisplay: "GameOver"
      }
  }
}

The issue with the code above arises from the fact that the assignments in appStateReducer are treated as type String instead of being recognized as type AppDisplay by TypeScript. How can I enforce that appDisplay can only be assigned values of "Game", "GameOver", or "MainMenu"?

Answer №1

In addition to Oles' suggestion of specifying the return type for your function, there are ways to streamline your code further:

Start by creating an enum with your preferred values:

enum AppDisplay {
    MAIN_MENU,
    GAME,
    GAME_OVER
}

Utilize this enum in defining the AppState interface:

interface AppState {
    appState: AppDisplay
}

A similar approach can be taken with the ActionType:

enum ActionType {
    DIPLAY_MENU,
    DISPLAY_GAME,
    DISPLAY_GAME_OVER
}

Implementing enums allows you to set specific values without concerning yourself with the data type (string, number, etc.).

For your reducer function, consider something along these lines (note that the state parameter appears unused in your existing code):

const appStateReducer = (action: ActionType): AppDisplay => {
    switch(action) {
        case ActionType.DISPLAY_MENU: 
            return AppDisplay.MAIN_MENU;

        case ActionType.DISPLAY_GAME: 
            return AppDisplay.GAME;

        case ActionType.GAME_OVER: 
            return AppDisplay.DISPLAY_GAME_OVER;

    }
}

We hope you find these suggestions valuable. Best wishes.

Answer №2

To properly implement this function, make sure to specify the return type:

const appStateReducer = (state : AppState, action : ActionType): AppState => {
  ...
}

Another option is to declare the return object type as const:

return { ... } as const

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

Removing a field from a collection using firebase-admin: Tips and tricks

I currently have a collection stored in Firebase Realtime Database structured like this: https://i.sstatic.net/jNiaO.png My requirement is to remove the first element (the one ending with Wt6J) from the database using firebase-admin. Below is the code s ...

Understanding the significance of an exclamation point preceding a period

Recently, I came across this code snippet: fixture.componentInstance.dataSource!.data = []; I am intrigued by the syntax dataSource!.data and would like to understand its significance. While familiar with using a question mark (?) before a dot (.) as in ...

Display captions on react-player videos using an .srt file

Currently, I am working on a React/Typescript project with Next.js. A key feature of this project is a modal that utilizes 'react-player' to display videos. While the video and modal are functioning as intended, I am looking to incorporate capti ...

Utilize the index of a for loop to manipulate an Angular string

When working with different objects and creating forms simultaneously, I've come across a challenge. My initial idea for handling the submission was to use the following code: <form (ngSubmit)="submitForm{{u}}()"> However, incorporating the in ...

The issue of `Console.log` displaying as undefined arises after subscribing to a provider in Ionic3

In the process of implementing the Spotify api into my Ionic 3 app, I encountered an issue where the data retrieved appears as undefined when attempting to log it. Let me share some code and delve deeper into the problem. Here is the function getData() tha ...

typescript is throwing an error because it cannot read the property 'filter' of an undefined variable

Whenever this code is executed, the following error is displayed: Cannot read property 'filter' of undefined contrat: Contrat[]; gpss: GPS[]; homeboxp: HomeboxP[]; sensors: Sensors[]; homebox: Homebox[]; getProductName(productid: s ...

Regular expression for the validation of emails using a delimiter

Can someone help me create a regex expression for emails? This is what I have so far: \S+@\S+\.\S+ I want to repeat this X times with a ; separator. Any ideas on how to achieve this? For example, the pattern should allow strings like: ...

Ensure that the JSON file containing translations is fully loaded prior to proceeding with the loading of the Angular application

In our Angular application, we have integrated internationalization using ng2-translate. We are utilizing the .instant(...) method for translations to simplify the process without having to subscribe to observables. One issue we are facing is that using . ...

The ngOnChanges method fails to exhibit the anticipated modifications in a variable

Trying to grasp the concept of the ngOnChanges() callback, I created an example below. Despite having values for the attributes title and content in the Post interface during compile time, I do not see any logs from ngOnChanges. Please advise on the corre ...

How to efficiently fetch Redux state through reducers with an action-based approach

Utilizing Redux actions to manage a list of contacts, I am facing an issue where I am unable to retrieve the actual state contact. Despite setting the contact in the action, all I receive is the contact set within the action itself. Can someone guide me on ...

creating a JSON array within a function

I am currently developing an Angular application and working on a component with the following method: createPath(node, currentPath = []){ if(node.parent !==null) { return createPath(node.parent, [node.data.name, ...currentPath]) } else { retu ...

Building a table with Next.js

I need assistance in displaying users and their metadata in a table on my website. Here is the code snippet I have: const apiKey = process.env.CLERK_SECRET_KEY; if (!apiKey) { console.error('API_KEY not found in environment variables'); proc ...

Exploring the functionality of window.matchmedia in React while incorporating Typescript

Recently, I have been working on implementing a dark mode toggle switch in React Typescript. In the past, I successfully built one using plain JavaScript along with useState and window.matchmedia('(prefers-color-scheme dark)').matches. However, w ...

Unfortunately, the utilization of an import statement outside a module is restricted when working with Electron

Is there a solution to the well-known problem of encountering the error message "Cannot use import statement outside a module" when working with an Electron-React-Typescript application? //const { app, BrowserWindow } = require('electron'); impor ...

Traverse the elements of a BehaviorSubject named Layer_Template

I am currently facing an issue with displaying data from my BehaviorSubject. I have come across a way to iterate through a BehaviorSubject using asyncpipe which subscribes to the Observable SERVICE todo.service.ts @Injectable() export class TodoService ...

Converting <reference path/> directive to ESM import: A step-by-step guide

As I embark on developing a TypeScript application, I've reached the realization that I am not a fan of using the <reference path /> triple-slash directive. Instead, I prefer utilizing import 'something'. However, every time I attempt ...

Function exported as default in Typescript

My current version of TypeScript is 1.6.2 and we compile it to ECMA 5. I am a beginner in TypeScript, so please bear with me. These are the imported library typings. The contents of redux-thunk.d.ts: declare module "redux-thunk" { import { Middle ...

Transform OKTA Observable into a practical string variable

I'm currently in the process of developing a service in Angular 12 that retrieves a "User" object, with OKTA being used for authentication. My goal is to streamline the process. I can easily obtain the family name as an Observable using the following ...

TS2339: The attribute 'size' is not present on the 'string' data type

Within my Typescript file, I have the following line: return stringToValidate.length <= maxLength; Despite the code executing without issues, an error is displayed: TS2339: Property 'length' does not exist on type 'string'. I am cu ...

Create a Typescript type extension specifically designed for objects with nested arrays of objects

After stumbling upon this inquiry, I am eager to adjust my code in a similar fashion, utilizing typescript and a more intricate object. Consider the type below: export type ImportationType = { commercialImportation: boolean dateToManufacturer: string ...