Reputation: 2285
I have a function which transforms an object into another with very specific rules. I guess the following function can serve as an example:
interface SomethingWithAValue<T> {
value: T;
}
function transform(obj) {
let value = {};
for(let key in obj) {
value[key] = obj[key].value;
}
return { value };
}
This basically transforms an object of type (pseudocode)
{
[key 1]: SomethingWithAValue<type 1>,
[key 2]: SomethingWithAValue<type 2>,
...
[key n]: SomethingWithAValue<type n>
}
into a new object of type (again pseudocode)
SomethingWithAValue<{
[key 1]: type 1,
[key 2]: type 2,
...
[key n]: type n
}>
I still need to add a proper type declaration to transform
, so what is the best approach here?
Upvotes: 0
Views: 50
Reputation: 329553
Ah, you need mapped types and inference from mapped types.
Here's how you use a mapped type to represent the mapping from a regular object to one in which all the property values are wrapped in SomethingWithAValue<>
:
type SomethingMapper<T> = {
[K in keyof T]: SomethingWithAValue<T[K]>
}
type Example = {
a: string,
b: number
}
type SomethingMappedExample = SomethingMapper<Example>;
// {
// a: SomethingWithAValue<string>;
// b: SomethingWithAValue<number>;
// }
And here's how you use inference from mapped types to type the function which unwraps:
function transform<T>(obj: SomethingMapper<T>): T {
// implementation
}
declare let mappedExample: SomethingMappedExample;
const unwrapped: Example = transform(mappedExample); // okay
Hope that helps. Good luck!
Upvotes: 1