TypeScript type not working with spread operator

余生颓废 提交于 2019-12-12 18:03:16

问题


I have a redux style reducer (I'm using ngrx) that is returning a specific type. When I use the spread operator in my return object, the typescript linter is not catching invalid properties.

Here is my interface:

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

Here is my reducer. Action is an ngrx action:

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

I would expect that propertyDoesNotExist would be flagged, but it is not. I've tried casting <CalendarState> the return object, the state property ...(<CalendarState>state) and using the as alias, but it doesn't help.

It's like the spread operator messes up the types.


回答1:


By using ...state, the returned expression is no longer an object literal, and TypeScript won't complain if it's a subtype of the return type (i.e. has extra properties). I ran into this problem myself and wrote a little helper function to signal extra properties:

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

(using Object.assign instead of spread operators because of this issue: https://github.com/Microsoft/TypeScript/issues/14409)

To use applyChanges, simply replace

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

with

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


来源:https://stackoverflow.com/questions/44525777/typescript-type-not-working-with-spread-operator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!