0
I got the following
Interface
interface UserState {
id: string;
isDeleted: boolean;
deletedAt: null | string;
name: string;
email: string;
picture: string;
}
Object
const state: UserState = {
id: '',
name: '',
email: '',
deletedAt: null,
isDeleted: false,
picture: ''
}
I am using vuex as central state lib and need to create a method (Mutation) that receives a payload (objeto: Partial<UserState>
) and updates the state (objeto: UserState
)
Attempt with spread Operator
// mutation
SET_INFO (state: UserState, payload: Partial<UserState>) {
state = {...state, ...payload}
}
The above example is not functional because this way vuex is not able to act reactively, perhaps because it overwrites the whole state.
Try with Object.Keys
SET_INFO (state: UserState, payload: Partial<UserState>) {
type UserStateKeys = keyof UserState
const keyNames: UserStateKeys[] = Object.keys(state) as UserStateKeys[]
keyNames.forEach((keyName) => {
if (payload[keyName]) {
state[keyName] = payload[keyName]
}
})
}
This one with pure Javascript is functional, but in typescript there is the following impeditive
Type 'string | Boolean | null | Undefined' is not Assignable to type 'Never'. Type 'Undefined' is not Assignable to type 'Never'. ts(2322) (Parameter) keyName: keyof Userstate
From what I understand of the message, when I use the keyName
as index no payload
, cannot accurately determine the type of value returned to state[keyName]
.
Line of error message
state[keyName] = payload[keyName]
So much so that if I do it here is accepted
state.email = payload[keyName] as string
Is there any way I can do this typing?
Instead of using the Operator spread to do the merge properties, use the function
Object.assign
, which has semantics ofset
(what works for the way Vuex treats the state). See more on What is the difference between Object.assign and spread Operator?.– Luiz Felipe
Maybe it’s worth [Dit] the question to make it a little wider (the Vue part doesn’t have much to do with the error you’re actually having with Typescript).
– Luiz Felipe
Good, as I agree with Vue having nothing to do with the typing problem. But I put it to contextualize where the code will be executed, in the expectation that someone would bring a solution according to this situation in vuex Mutation.
– ayelsew