I have a type like this:
type BooleanResult<T> = {
[K in keyof T]: T[K] extends object ? BooleanResult<T[K]> : boolean[]
}
Having these two types:
type ContactPerson = {
firstName: string
lastName: string
}
type Customer = {
companyName: string
contactPerson: ContactPerson
}
When creating a type from it like this:
type Result = BooleanResult<Customer>
it works as expected but the type info shows this:
type Result = {
companyName: boolean[];
contactPerson: BooleanResult<{
firstName: string;
lastName: string;
email: string;
}>;
}
What do I need to change to reflect correct information like this
type Result = {
companyName: boolean[];
contactPerson: {
firstName: boolean[];
lastName: boolean[];
email: boolean[];
};
}
CodePudding user response:
One trick that often works to force the compiler to eagerly evaluate a type is to use conditional type inference with infer
to "copy" the type in question to a new type parameter, and then use the copy:
type BooleanResult<T> = {
[K in keyof T]: T[K] extends object ? BooleanResult<T[K]> : boolean[]
} extends infer O ? O : never
For your example, this results in:
type Result = BooleanResult<Customer>
/* type Result = {
companyName: boolean[];
contactPerson: {
firstName: boolean[];
lastName: boolean[];
};
} */
as desired.
Other "no-op" tricks that seem to have the same effect:
a union with the
never
type:type BooleanResult<T> = { [K in keyof T]: T[K] extends object ? BooleanResult<T[K]> : boolean[] } | never
an intersection with the
unknown
type:type BooleanResult<T> = { [K in keyof T]: T[K] extends object ? BooleanResult<T[K]> : boolean[] } & unknown
... (more later?)