The recognition of Angular ngrx union type actions is hindered by discrepancies in constructors

The actions classes and union type are displayed below. Unfortunately, these actions are not being recognized during the application's execution.

export class Login implements Action {
  readonly type = LOGIN;
  constructor(
    public payload: {
      userID: string;
      email: string;
      token: string;
      expirationDate: Date;
    }
  ) {}
}

export class Logout implements Action {
  readonly type = LOGOUT;
  constructor() {}
}

export class LoginStart implements Action {
  readonly type: string = LOGIN_START;
  constructor(public payload: { username: string; password: string }) {}
}

export class LoginFail implements Action {
  readonly type: string = LOGIN_FAIL;
  constructor(public payload: string) {}
}

export type AuthActions = Login | Logout | LoginStart | LoginFail;

Upon running the application, an error is thrown by ng serve:

ERROR in src/app/auth/store/auth.reducer.ts:23:16 - error TS2339: Property 'payload' does not exist on type 'AuthActions'.
  Property 'payload' does not exist on type 'Logout'.

23         action.payload.userID,
                  ~~~~~~~
src/app/auth/store/auth.reducer.ts:24:16 - error TS2339: Property 'payload' does not exist on type 'AuthActions'.
  Property 'payload' does not exist on type 'Logout'.

24         action.payload.email,
                  ~~~~~~~
src/app/auth/store/auth.reducer.ts:25:16 - error TS2339: Property 'payload' does not exist on type 'AuthActions'.
  Property 'payload' does not exist on type 'Logout'.

25         action.payload.token,

If anyone has insights on how to address this issue without altering the constructors, please provide guidance.

I have reviewed several discussions but have yet to find a suitable solution. Typescript discriminated union type not recognized

Answer №1

The error message indicates that the specified property (payload) does not exist on Logout. In some cases, it is advisable to consider using the ActionWithPayload<T> utility type alongside Action, as certain actions may or may not have a payload.

This issue pertains to the architecture itself rather than the implementation.

If you incorporate the ActionWithPayload<T> utility type, you can verify whether the given instance includes the payload property.

To begin with, you would need the utility interface:


interface ActionWithPayload<T = any> {
  payload: T;
}

Subsequently, you would require a utility function to determine if the provided object is an instance of ActionWithPayload<T>


function hasPayload(actionWithPayloadLike: any): actionWithPayloadLike is ActionWithPayload {
  return 'payload' in actionWithPayloadLike;
}

You can then utilize this function to confirm the existence of the relevant property within the instance:


const loginFailAction: AuthActions = new LoginFail("test");
if(hasPayload(loginFailAction)) {
  alert(loginFailAction.payload);  // will display an alert
}

and


const logoutAction: AuthActions = new Logout();
if(hasPayload(logoutAction)) {
  alert(logoutAction.payload);  // will not trigger an alert
}

For improved code organization, it is recommended to implement the interface within the classes instead of solely utilizing Action.

Answer №2

After some investigation, it was determined that the issue stemmed from using the "string" type for certain actions but not for others. By simply removing the type definition, the problem was resolved. Correction: Verify that the 'type' is no longer set to 'string'.

export class LoginStart implements Action {
  readonly type = LOGIN_START;
  constructor(public payload: { username: string; password: string }) {}
}

export class LoginFail implements Action {
  readonly type = LOGIN_FAIL;
  constructor(public payload: string) {}
}

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

Create a recursive CSS style for an angular template and its container

I am struggling with styling CSS inside an ng-container that is used in a tree recursive call to display a tree hierarchy. <ul> <ng-template #recursiveList let-list> <li *ngFor="let item of list" [selected]="isSelected"> <sp ...

Converting POST data into an array using Angular

I am facing an issue with my post request setup in a NodeJS app. The data sent returns as an array, but I am struggling to convert it into the desired format. My Angular code is structured as follows: newWord = ''; keyword = ''; onCli ...

Removing buttons from a table row dynamically

Below is how I am adding the Button to Element: (this.sample as any).element.addEventListener("mouseover", function (e) { if ((e.target as HTMLElement).classList.contains("e-rowcell")) { let ele: Element = e.target as Element; let ro ...

Using RxJS and the combineLatest function can be hit or miss in terms of reliability

When you call this function multiple times with the values of observables obs1 and obs2 being the same each time, the returned array may not always be the same. getUniqueProducts(obs1: Observable<any>, obs2: Observable<any>): Observable<any& ...

Download and store the response body using FileSaver and blob technology

I'm encountering an issue where I am trying to download and save a file from an API. The original filename is text.txt, but after saving, the file is named: _text.txt_. Additionally, the content of this saved file is displaying as: [object Object] Be ...

Issue with displaying international characters when using HttpClient's http.get() function in Angular.The

I am facing an issue that I can't quite figure out as I am new to Angular. My goal is to read a local .csv file and display its contents in a table. Everything seems to be working fine, except for the fact that when special characters like "č, ć, š ...

Getting a specific piece of information from a JSON file

I am encountering an issue with my JSON file collection. When I access it through http://localhost:5000/product/, I can see the contents without any problem. However, when I try to retrieve a specific product using a link like http://localhost:5000/product ...

Generating an interactive table using JSON with Angular 5

Can a dynamic table with dynamic columns be created based on a JSON object using Angular 5? If yes, how? The API response includes the following JSON: { "ResponseStatus": true, "ResponseData": [ { "Parent": "Company 1", ...

Zod data structure featuring optional fields

Is there a more efficient way to define a Zod schema with nullable properties without repeating the nullable() method for each property? Currently, I have defined it as shown below: const MyObjectSchema = z .object({ p1: z.string().nullable(), p2 ...

The custom validation feature in Angular 4 is failing to function as expected

Currently, my focus is on Angular 4 where I have developed a custom validator for checking CGPA values (to ensure it is between 2.0 and 4.0). Although the predefined `Validators.required` works fine, my custom validator seems to be not triggering as expect ...

Which specific part is the perfect choice?

I am currently in the process of developing a small app that connects to an API through Node.js and stores all posts in MongoDB. While I have completed this part successfully, I am now faced with the challenge of creating the front-end interface. The use ...

What's the best approach for revalidating data with mutate in SWR?

Whenever a new album is created in my app, the post request response includes an updated list of all albums. To enhance the user experience, I wanted the newly created content to automatically show up without requiring a page refresh. Although I am famil ...

Tips on preventing pooling in Angular 5

service.ts: // Fetch all AgentLog logs using pooling method getAgentLogStream(): Promise<string> { const url = `${this.testCaseUrl}/logfile`; return Observable .interval(5000) .flatMap((i)=> this.http.get(url).toPromise().then(respons ...

Comparison between a Typescript optional field and a field that has the potential to be undefined

Can you clarify the contrast between an optional field and a T | undefined field? export interface Example { property1: string | undefined property2?: string } ...

Creating number inputs in Ionic 2/3 using alerts

I am currently working with Ionic 3.x on my macOS system. The issue I am facing is as follows: I have an array that contains a number and another array consisting of names. table: { number: number, names: string[] } = { number: 0, names: ['& ...

What are some ways to utilize tuples in TypeScript along with generics?

My mission is to create a type safe mapping object where I can define key/value pairs just once. I've managed to achieve this with the code below: const myPropTuple = [ [0, "cat"], [1, "dog"], [2, "bird"] ] a ...

Is it possible to automatically switch to a different route in a Next.js server component after a certain period of time?

Is it possible to achieve a similar function in an async server component: displaying the ui, waiting 3 seconds, and then redirecting to another route? In a client component, you can accomplish this using: useEffect(() => { function delay(ms: number) ...

Angular script error when running 'npm run' on select computers causing Unix command issues for some users but not all

Recently, I've encountered a puzzling issue at my workplace that has been difficult to diagnose. We utilize scripts in npm within the Angular framework to launch a local server instance. Strangely enough, some of my colleagues' computers are thro ...

What is the best way for me to generate a fresh object?

In one of my components, I have implemented a feature where clicking on an image toggles a boolean variable to show or hide a menu. The HTML structure for this functionality is as follows: <img src="../../assets/image/dropdown.png" class="dropdown-imag ...

Typescript: Subscribed information mysteriously disappeared

[ Voting to avoid putting everything inside ngOnit because I need to reuse the API response and model array in multiple functions. Need a way to reuse without cluttering up ngOnInit. I could simply call subscribe repeatedly in each function to solve the p ...