在TypeScript中是否可以映射对象值类型?

6
例如,我有一个以下形式的函数:
function wrap<T>(item: T): W<T> {
}
interface W<T> {
  item: T;
}

是否可以编写函数 (mapValues),通过应用此 wrap 函数转换给定对象值并返回正确类型的对象?我了解如何编写实际函数(lodash的_.mapValues将很好地工作),但我不知道是否可以应用适当的类型。

是否可以编写mapValues函数以便以下内容可以编译?

interface Before {
  a: number;
  b: string;
}

interface After {
  a: W<number>;
  b: W<string>;
}

let obj1: Before = { a: 1, b: "2" };
let obj2: After = mapValues(obj1);

function typecheck_number(arg: number) {}
function typecheck_string(arg: string) {}
typecheck_number(obj2.a.item);
typecheck_string(obj2.b.item);
2个回答

4
以下是一个可能的解决方案:
interface W<T> {
  item: T;
}
function mapValues<T>(obj: T): {[K in keyof T]: W<T[K]>} {
  // implementation
}

很遗憾的是,类似的递归方法似乎不可能,但有希望通过这个提案中的类型约束来实现。

这个链接对于得出这个解决方案非常有帮助。


0

是的,你在原帖中的类型是正确的。mapValues 只需要标记返回 After 类型即可。

这里有一个TS playground,展示了如果mapValues返回After类型的示例正常工作。

映射对象的属性类型为Wrap<T>


不,这个想法是使mapValues成为通用的,因此它将在任何其他接口上以这种方式工作(不仅仅是Before和After - 它们只是一个示例)。 - Rogach
@Rogach 如果mapValues的类型声明是mapValues<T>(obj: any): T,那么这样不就可以了吗? - Shane
1
不行,因为那样我就需要明确地写出 mapValues<{ prop1: T1, etc...}>()(编译器无法推断T)。这个想法是返回类型自动取决于参数类型,类型检查器可以提供指导(从而帮助我作为程序员避免错误)。 - Rogach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接