ngrx Reducer 属性在类型上不存在
2018-02-26
2336
我使用的是 TypeScript 2.7.1 和 ngrx。我的操作如下所示:
import { Action } from '@ngrx/store';
export const HEALTH_FORM_CONTENT_CHANGED = '[setupHealthForm] Content Changed';
export const HEALTH_FORM_TITLE_CHANGED = '[setupHealthForm] Title Changed';
export class SetupHealthFormContentChangedAction implements Action {
public type: string = HEALTH_FORM_CONTENT_CHANGED;
constructor(public payload: { content: string }) { }
}
export class SetupHealthFormTitleChangedAction implements Action {
public type: string = HEALTH_FORM_TITLE_CHANGED;
constructor(public payload: { title: string }) { }
}
export type Actions
=
SetupHealthFormContentChangedAction
| SetupHealthFormTitleChangedAction;
我的 Reducer 如下所示:
import { Actions, HEALTH_FORM_TITLE_CHANGED, HEALTH_FORM_CONTENT_CHANGED } from './setup-health-form.actions';
export interface State {
title: string;
body: string;
}
const initialState: State = {
title: '',
body: ''
}
export function reducer(state: State = initialState, action: Actions): State {
switch (action.type) {
case HEALTH_FORM_TITLE_CHANGED: {
return {
...state,
...{ title: action.payload.title }
}
}
case HEALTH_FORM_CONTENT_CHANGED: {
return {
...state,
...{ body: action.payload.content }
}
}
default: {
return state;
}
}
}
export const body = (state: State) => state.body;
export const title = (state: State) => state.title;
但是我收到以下 TypeScript 错误:
error TS2339: Property 'title' does not exist on type '{ content: string; } | { title: string; }'.
error TS2339: Property 'content' does not exist on type '{ content: string; } | { title: string; }'.
我发现解决此问题的唯一方法是导出具有 any 类型有效负载的操作。我该如何正确修复此问题以保留我的输入?
2个回答
要使用可区分联合类型及其
switch
类型保护行为,
type
的类型必须是字符串文字类型(基本上是只能是单个值的字符串类型)。即使您为
type
字段分配了一个常量,它也是
string
。发生这种情况是因为 typescript 假定您想要改变该字段,因此它将其类型化为
string
。如果您将其标记为
readonly
并删除显式
string
类型,该字段将使用常量的类型(即字符串文字类型)进行类型化,并且您的
switch
将正确键入检查:
export class SetupHealthFormContentChangedAction {
public readonly type = HEALTH_FORM_CONTENT_CHANGED;
constructor(public payload: { content: string }) { }
}
export class SetupHealthFormTitleChangedAction implements Action {
public readonly type = HEALTH_FORM_TITLE_CHANGED
constructor(public payload: { title: string }) { }
Titian Cernicova-Dragomir
2018-02-26
添加到
Titian
的现有答案中,就我的情况而言,如果
type
定义是字符串连接,则会发生错误(这是我的 IDE 设置的行为,称为硬换行,如果行太长则自动换行)。
您需要确保
type
是一个具体的单个 const 字符串。
不起作用
export const GET_SYSTEM_CLOSING_REPORT_OF_PROJECT_MANAGER = '[MonthClosingReportActions] Get System Closing Reports of' +
' project manager';
export class GetSystemClosingReportOfProjectManagerAction implements Action {
readonly type = GET_SYSTEM_CLOSING_REPORT_OF_PROJECT_MANAGER;
constructor(public payload: string) {}
}
工作
export const GET_SYSTEM_CLOSING_REPORT_OF_PROJECT_MANAGER = '[MonthClosingReportActions] Get System Closing Reports of project manager';
export class GetSystemClosingReportOfProjectManagerAction implements Action {
readonly type = GET_SYSTEM_CLOSING_REPORT_OF_PROJECT_MANAGER;
constructor(public payload: string) {}
}
ThangLeQuoc
2021-12-03