如何在 Typescript 中保留映射对象的类型

pet*_*est 4 typescript

如果我有一个字典对象,例如:

const x = {
  foo: {inner: 3},
  bar: {inner: 'hi'},
};
Run Code Online (Sandbox Code Playgroud)

哪里有一个不同类型的内部属性(例如这里的字符串和数字)。

然后我想将其映射到一个如下所示的结构:

const y = {
  foo: 3,
  bar: 'hi',
};
Run Code Online (Sandbox Code Playgroud)

不过,我希望能够自动执行此操作,而不会丢失任何类型信息。这在打字稿中可能吗?

几乎可以用 lodash 到达那里:

import { mapValues } from 'lodash';
const y: Y = mapValues(x, (z) => z.inner);
Run Code Online (Sandbox Code Playgroud)

然而,这最终会采用字典中所有类型的并集,并带有类型签名:

const y: {
    foo: string | number;
    bar: string | number;
}
Run Code Online (Sandbox Code Playgroud)

而不是想要的:

const y: {
  foo: number;
  bar: string;
};
Run Code Online (Sandbox Code Playgroud)

dba*_*tra 5

像这样的东西应该有效:

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);
Run Code Online (Sandbox Code Playgroud)

参考: https: //www.typescriptlang.org/docs/handbook/advanced-types.html(最后一段)