Reputation: 4452
If I have a dictionary object such as:
const x = {
foo: {inner: 3},
bar: {inner: 'hi'},
};
Where there is an inner property with varying type (string and number here for example).
Then I would like to map this to a structure which looks like:
const y = {
foo: 3,
bar: 'hi',
};
However I'd like to be able to do this automatically without losing any type information. Is this possible in Typescript?
I can almost get there with lodash:
import { mapValues } from 'lodash';
const y: Y = mapValues(x, (z) => z.inner);
However this ends up taking the union of all types in the dictionary, with the type signature:
const y: {
foo: string | number;
bar: string | number;
}
Rather than the desired:
const y: {
foo: number;
bar: string;
};
Upvotes: 4
Views: 1146
Reputation: 1314
Something like this should work:
type Wrapped<T> = {[K in keyof T]: {inner: T[K]}};
function unwrap<T>(x: Wrapped<T>): T {
// (the implementation here is not the point)
return _.mapValues(x as any, z => z.inner) as T;
}
const y = unwrap(x);
Reference: https://www.typescriptlang.org/docs/handbook/advanced-types.html (the very last paragraph)
Upvotes: 5