TypeScript 类型不适用于展开运算符

Ric*_*ort 5 typescript ngrx

我有一个 redux 风格的 reducer(我使用的是 ngrx),它返回一个特定的类型。当我在返回对象中使用扩展运算符时,打字稿 linter 没有捕获无效属性。

这是我的界面:

interface MyState {
    firstName: string;
    lastName: string;
    age: number;
}
Run Code Online (Sandbox Code Playgroud)

这是我的减速机。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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望这propertyDoesNotExist会被标记,但事实并非如此。我试过转换<CalendarState>返回对象、状态属性...(<CalendarState>state)并使用as别名,但它没有帮助。

这就像扩展运算符弄乱了类型。

Obl*_*sys 6

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

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

(Object.assign由于此问题,使用而不是扩展运算符:https://github.com/Microsoft/TypeScript/issues/14409)

使用时applyChanges只需更换

return {...state,
    propertyDoesNotExist: action.payload, // <- no error
};
Run Code Online (Sandbox Code Playgroud)

和

return applyChanges(state, {
    propertyDoesNotExist: action.payload, // <- error
});
Run Code Online (Sandbox Code Playgroud)