ngrx reducer属性在类型上不存在

tha*_*guy 2 typescript ngrx angular

我正在使用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;
Run Code Online (Sandbox Code Playgroud)

我的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;
Run Code Online (Sandbox Code Playgroud)

但是我得到以下打字稿错误:

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; }'.
Run Code Online (Sandbox Code Playgroud)

我发现解决此问题的唯一方法是导出具有任何类型的有效负载的操作.如何正确解决此问题以保留我的打字?

Tit*_*mir 5

要使用有区别的联合类型及其switch类型保护行为,类型type必须是字符串文字类型(基本上是只能是单个值的字符串类型).您的type字段string甚至通过为其分配常量.发生这种情况是因为typescript假定您不想改变字段,因此将其键入为string.如果将其标记为readonly并删除显式string类型,则将使用常量类型(字符串文字类型)键入字段,并且您switch将正确键入check:

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 }) { }
Run Code Online (Sandbox Code Playgroud)

游乐场示例代码

  • @that_guy我在操场上检查过它也适用于2.7.你从`type`中删除了显式类型吗?应该是`public readonly type = HEALTH_FORM_TITLE_CHANGED` NOT`public readonly type:string = HEALTH_FORM_TITLE_CHANGED` (3认同)