I have been working on creating a function that takes an object
A: { [key: string]: string | undefined }
as its parameter. The goal is to generate a new object B
with all properties from A
, converting each string
property to type number
, and each string | undefined
property to type number | undefined
.
To better clarify, here is a simplified example of the concept:
type Input<T> = { [K in keyof T]: string | undefined };
type Output<T> = { [K in keyof T]: T[K] extends undefined ? number | undefined : number };
function transformObject<T extends Input<T>>(input: T): Output<T> {
const result = {} as Output<T>;
for (const key in input) {
const value = input[key];
result[key] = value === undefined ? undefined : value.length;
}
return result;
}
const obj = { background: 'red', color: 'blue', border: undefined };
const obj2 = transformObject(obj);
const bgLength: number = obj2.background;
const borderLength: number | undefined = obj2.border;
The issue I am facing is figuring out how to properly define the assignment of result[key]
without resorting to using as any
for type casting. When I try to do so, I receive the following error message:
Type 'number | undefined' is not assignable to type 'T[Extract<keyof T, string>] extends undefined ? number | undefined : number'.
Type 'undefined' is not assignable to type 'T[Extract<keyof T, string>] extends undefined ? number | undefined : number'.ts(2322)
What would be the correct method to establish this type relationship between the input and output objects, where all properties in A
are mirrored in B
, while preserving optional properties as optional in B
?