I'd like to type a generic function to only include values that are of type object (and ignore/disallow the other ones).
This is to only allow updating objects within a map. Is it possible? I haven't been able to find a solution.
enum SKey {
key1 = "key1",
key2 = "key2",
}
type SItem = {
[SKey.key1]: boolean;
[SKey.key2]: {
attr1: string;
attr2: boolean;
};
};
const mapDB: SItem = {
[SKey.key1]: true,
[SKey.key2]: {
attr1: "hello",
attr2: true,
},
};
export function updateDbItem<K extends keyof SItem>(
key: K,
newFields: Partial<SItem[K]>
) {
const item: SItem[K] = mapDB[key];
mapDB[key] = { ...item, ...newFields };
}
But obviously I get the following error
error TS2698: Spread types may only be created from object types.
mapDB[key] = { ...item, ...newFields };
~~~~~~~~
Thank you for your help!
You can use a mapped type to derive a union of only the keys whose values are object types.
Here's an example:
TS Playground
See also: the utility type
Record<Keys, Type>