In the Further Exploration example on TypeScript website they show us a way to replace the type of a property with a different type based on some conditions.
How can we do the same but in a recursive way? i.e. not only map the first level properties, but any nested property that passes the check.
The example:
type ExtractPII<Type> = {
[Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
};
type DBFields = {
id: { format: "incrementing" };
name: { type: string; pii: true };
};
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
// type ObjectsNeedingGDPRDeletion = { id: false; name: true; }
What I need:
type DBFields = {
id: { format: "incrementing", foo: { type: string; pii: true } };
name: { type: string; pii: true };
};
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
// type ObjectsNeedingGDPRDeletion = { id: { format: string; foo: true }; name: true; }
CodePudding user response:
In the false
case, you just need to execute another check to see if the type is an object, and then call ExtractPii
on that property.
type ExtractPII<T> = {
[P in keyof T]: T[P] extends { pii: true }
? true
: T[P] extends object
? ExtractPII<T[P]>
: T[P];
};
This will results in:
type DBFields = {
id: { format: "incrementing", foo: { type: string; pii: true } };
name: { type: string; pii: true };
};
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
const a: ObjectsNeedingGDPRDeletion = {
name: true,
id: {
foo: true,
format: "incrementing"
}
}
If you want in the false
case the value false
, then just replace T[P]
with false
:
type ExtractPII<T> = {
[P in keyof T]: T[P] extends { pii: true }
? true
: T[P] extends object
? ExtractPII<T[P]>
: false;
};