I have the following type shape:
Record<string, Record<string, unknown>>
Which for example can be typed like this:
{
body: {
user: {
name: string;
age: number;
}
},
query: {
id: string;
strict?: boolean;
},
params: {
id: number
scope: string[]
},
}
I would like to introduce an utility type Flatten
that accepts two arguments. The first argument would be a single generic type like the type I described above. The second argument would accept a tuple or union type of top level keys of the object that was provided inside the first argument of the utility type.
So the utility type Flatten<object, 'query' | 'params' | 'body'>
, where object
is the object described above for the sake of simplicty, should turn it in the following type:
{
id: number;
strict?: boolean;
scope: string[]
user: {
name: string;
age: number;
}
}
As you can see, the values of the top level of objects get spread in the order that was given inside the second argument. The second argument should always contain all the top level keys that are present inside the provided object of the first argument. Duplicate keys get overridden by objects that occurre in the provided order inside the second argument of the utility type.
No recursion should occurre, so the deeper nested objects stay intact. So flattening should only happen once.
How would I accomplish this?