Let’s say I’ve this type
type Form = {
collateral: {
id: "collateralField",
default: "",
deps: ["collateralToken", "borrowInput", "asd"],
severities: {
first: 'first',
second: 'second'
}
},
borrow: {
id: "borrowField",
name: "Borrow"
},
}
I’d like to create a generic that takes the type Form and a string Query. It should return an union of all the values of the Queried keys.
type IDs = DeepKeys<Form, "id">
// Expected: "collateralField" | "borrowField"
This is my progress
type DeepKeys<T, Q> =
T extends object
? { [K in keyof T]: (K extends Q ? T[K] : never) | DeepKeys<T[K], Q> }[keyof T]
: never;
It seems to loop into the array object and append some unnecessary stuff.
>Solution :
You nearly got it.
The problem is that TypeScript is recurisively iterating over all keys, including those of arrays. That creates issues as there are unncecessary keys in your final type.
Here is a fix:
type DeepKeys<T, Q> = T extends object
? {
[K in keyof T]: T[K] extends (infer R)[]
? never
: K extends Q
? T[K]
: DeepKeys<T[K], Q>
}[keyof T]
: never;
Just tested this out and seemed to work fine on the TS playground.
With this improved version, you can do the following
type IDs = DeepKeys<Form, "id">;