I'm attempting to type the value that I need to put into the property of an object. See below.
interface SliceStateType {
TrptLimit: number;
TrptOffset: number;
someString: string;
someBool:boolean;
}
interface SettingType {
key: keyof SliceStateType;
value: number | string | boolean;
}
const initialState: SliceStateType = {
TrptLimit: 10,
TrptOffset: 0,
someString: 'my string',
someBool:false,
};
// settings is the same shape as initialState
settings[key] = value as WHATGOESHERE;
I am trying to type value
to the exact type of whatever key
is.
I was thinking maybe WHATGOESHERE
would be SliceStateType[typeof key]
but that does not work.
The error is Type 'string | number | boolean' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'.
I thought that would have returned the concrete type for that specific key. I am trying to do something like
settings[keyOfSlice] = value as SliceStateType['tRptLimit'];
but replacing tRptLimit with something dynamic based on "key" Any ideas?
CodePudding user response:
function set<T extends Record<never, never>, K extends keyof T>(
object: T, key: K, value: T[K]
) {
object[key] = value;
}
CodePudding user response:
Hmm. I'm not sure if you can do exactly what you're trying to do, but I'm not quite sure what that is. Typescript "erases" the types when it converts to Javascript, so you can't access them "dynamically", which I think is what you are asking.
You can get the type of a specific property, using this notation I don't see in your code:
let foo1: SliceStateType['TrptLimit'] // number
Another thing you can do is extract all the keys from an object type using keyof
:
let foo2: keyof SliceStateType = 'TrptLimit' // ok
let foo3: keyof SliceStateType = 'no' // not ok
But you can't write a strongly typed version of settings[someVariable] = value
, unless someVariable
is typed very specifically to a certain string (or set of strings). What follows are some of the possibilities:
let someVariable: 'TrptLimit' = 'TrptLimit'
settings[someVariable] = ... will expect a number
You can even specify the type as
let someVariable: 'TrptLimit' | 'TrptOffset' = 'TrptLimit'
settings[someVariable] = ... will expect a number
But if someVariable
has other keys, you lose some specific type checking:
let someVariable: keyof SliceStateType = 'TrptLimit'
settings[someVariable] = ... number|string|boolean
I hope this helps. This can be confusing initially.