2017-06-13 52 views
0

我有一个正在返回特定类型的redux风格reducer(我正在使用ngrx)。当我在返回对象中使用传播运算符时,打字稿不会捕获无效属性。TypeScript类型不与扩展运算符一起工作

这里是我的接口:

interface MyState { 
    firstName: string; 
    lastName: string; 
    age: number; 
} 

这里是我的减速器。 Action是NGRX动作:

function reducer(state = initialState, action: Action): MyState { 
    switch (action.type) { 
     case Actions.COOL_ACTION: 
      return { 
       ...state, 
       propertyDoesNotExist: action.payload, // <- no error 
      }; 
     default: 
      return state; 
    } 
} 

我预计propertyDoesNotExist将被标记,但事实并非如此。我试过铸造<CalendarState>的退货对象,国家财产...(<CalendarState>state)和使用as别名,但它没有帮助。

这就像传播运算符混淆了类型。

+0

您正在描述您的示例中未定义的类:Action,Actions,CalendarState。你能完成你的例子吗?最好还是在[code](https://www.typescriptlang.org/play/)中提供。 – Raven

+1

好吧,就像有人问一个.NET问题,然后一个评论者说:“我们不知道你在使用什么.NET类,你可以添加这些类吗?”并非如此,我无法真正添加ngrx库的代码。这就是为什么我开始说...一个... redux风格的减速器...我可以调整我的问题来显示这个问题,但我不得不提出这个例子。这基本上就是我现在正在使用的代码。 –

回答

1

通过使用...state,返回的表达式不再是对象字面量,并且如果它是返回类型的子类型(即,具有额外的属性),则TypeScript不会抱怨。我就遇到了这个问题,我自己写了一个小的辅助函数信号额外的属性:

const applyChanges = <S, K extends keyof S>(state : S, changes : Pick<S, K>) : S => 
    Object.assign({}, state, changes); 

(使用Object.assign,而不是传播经营者,因为这个问题:https://github.com/Microsoft/TypeScript/issues/14409

要使用applyChanges,只需更换

return {...state, 
    propertyDoesNotExist: action.payload, // <- no error 
}; 

return applyChanges(state, { 
    propertyDoesNotExist: action.payload, // <- error 
}); 
相关问题