-
-
Save gomezcabo/dff1d95fd1eb354f686d6606a511d7da to your computer and use it in GitHub Desktop.
type RecursiveRequired<T> = Required<{ | |
[P in keyof T]: T[P] extends object | undefined ? RecursiveRequired<Required<T[P]>> : T[P]; | |
}>; | |
type ExampleType = { | |
a?: number; | |
b: number; | |
c?: { | |
d?: { | |
e?: number; | |
f: boolean; | |
g?: { | |
h: string | |
} | |
} | |
} | |
} | |
type ExampleTypeRequired = RecursiveRequired<ExampleType> | |
const data: ExampleTypeRequired = { | |
a: 1, | |
b: 1, | |
c: { | |
d: { | |
e: 1, | |
f: false, | |
g: { | |
h: 'hello' | |
} | |
} | |
} | |
} |
Good catch! What about updating the DeepRequired type?
type DeepRequired<T> = T extends Function
? T
: T extends object
? Required<{
[K in keyof T]-?: T[K] extends PropertyKey ? T[K] : DeepRequired<T[K]>;
}>
: T;
Now, if T[K]
is not an object, but a PropertyKey
(e.g. string | number | symbol
) we use that type (keyof T
in your case).
What do you think @C-Duxbury ?
Link to playground here.
@gomezcabo Yes, that does the trick nicely! Thanks!
Just for my own academic curiosity, do you know why the TS compiler was saying 'string' is not assignable to type 'DeepRequired<keyof T>'
? It seems like they should be compatible.
@gomezcabo Yes, that does the trick nicely! Thanks!
Just for my own academic curiosity, do you know why the TS compiler was saying
'string' is not assignable to type 'DeepRequired<keyof T>'
? It seems like they should be compatible.
I guess when passing down the keyof T
to the generic, this one could be string
, number
or symbol
and that's where the Type was failing. No way to determine which one of those. That's why the fix was to include the check T[K] extends PropertyKey
(PropertyKey === string | number | symbol
).
@kennarddh Is there any way to make this work with a generic type that references its own type? For example:
This interface could represent a table column definition that requires the name of a valid property from the row item schema. Currently, this produces a type that makes
mappedProperty
of typeDeepRequired<keyof T>
when applied toTableColumn<T>
instead of leaving it askeyof T
.This creates a problem when attempting to create objects that satisfy this in a mapping function:
TS playground link.