Reputation: 109
My code:
const state = { activeRequests: 0, test: true };
type state = typeof state;
type pState = Partial<state>;
type stateKeys = keyof state; // "activeRequests" | "test"
...
set: (state: state, p: pState) => Object.keys(p).forEach(k => (state[k] = p[k]))
Error at state[k] = p[k]
:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ activeRequests: number; test: boolean; }'.
No index signature with a parameter of type 'string' was found on type '{ activeRequests: number; test: boolean; }'
Looks like k
has string
type.
There are some of my attempts:
Object.keys(p).forEach((k: stateKeys) => state[k].push(p[k]))
Error: Type 'string' is not assignable to type '"activeRequests" | "test"'`.
Object.keys(p).forEach(k => (state[k as stateKeys] = p[k])
Error: Type 'any' is not assignable to type 'never'`
(Object.keys(p) as stateKeys[]).forEach(k => (state[k] = p[k]))
Error: Type 'number | boolean | undefined' is not assignable to type 'never'.
Type 'undefined' is not assignable to type 'never'.
What is wrong?
Upvotes: 0
Views: 103
Reputation: 2912
You can't do that cleanly without generics. Plus you are trying to assign a partially undefined value to a type that doesn't allow undefined. So you need to handle that scenario. Here's a potential solution:
var t = function<TState>(state: TState, p: Partial<TState>) {
let keys = Object.keys(p) as (keyof TState)[];
for (let key of keys) {
state[key] = p[key] ?? state[key];
}
}
Upvotes: 1
Reputation: 262
because you are trying to assing object like this:
{
activeRequests: number | boolean | undefined,
test: number | boolean | undefined
}
to:
{
activeRequests: number,
test: boolean,
}
because of the partial and stateKeys part.
Solution is simple like that:
const set = (state: state, p: pState) => ({...state, ...p})
Upvotes: 1