I\'d like to map an object recursively so that the primitive values in the object are converted to some other type.
For example, I\'d like an object like this:
So you need two things from the ConvertToTest
type. One is that if T
is a primitive type, then CovertToTest
. The other is that if T
isn't primitive, you want to keep the same keys but convert their values.
To do that, I'd just add the first case as one part of a conditional type, and then have the other branch use a recursive mapped type:
type Primitive = string | number | boolean | null | undefined;
type ConvertToTest = T extends Primitive ? Test : {
[K in keyof T]:
T[K] extends (infer U)[] ? ConvertToTest[] :
ConvertToTest;
}
Using that, you can then use it like so:
// For example. Replace with whatever your actual type is.
type test = {
foo(): string;
}
declare function convertToTest(obj: T): ConvertToTest;
const test = convertToTest({ a: "", b: { c: true, primArr: [1, ""], objArr: [{inner: ""}] } });
test.a.foo(); // OK
test.b.c.foo(); // OK
test.b.primArr[0].foo() // OK
test.b.objArr[0].inner.foo() // OK
This is a nice way to do it since it will work for objects of any depth, and will properly handle converting the elements of an array type as well.