TypeScript中从导入接口创建映射类型时MappedType为空
问题原因及解决方案
为什么映射类型是空对象?
TypeScript的接口属于类型系统专属概念,编译成JavaScript时会被完全擦除,不会留下任何运行时痕迹。你用import * as MyInterfaces from 'interfaces.ts'导入的是运行时的模块对象,这个对象里根本没有Foo/Bar/Baz这些接口的信息,所以typeof MyInterfaces得到的是空对象类型,基于它做映射自然会得到{}。
简单说:类型(接口)和值(变量、类等)是TypeScript里两个完全独立的空间,你试图从值空间的模块对象里获取类型空间的接口信息,这是行不通的。
正确的实现方式
要实现你想要的映射类型,得在类型层面定义一个包含所有接口的映射,再基于这个映射来创建新类型:
1. 修改interfaces.ts,新增类型映射
// interfaces.ts export interface Foo {} export interface Bar {} export interface Baz {} // 定义一个包含所有接口的类型映射,把接口名称和对应的类型关联起来 export type InterfaceMap = { Foo: Foo; Bar: Bar; Baz: Baz; };
2. 在consumeInterfaces.ts中使用这个类型映射
// consumeInterfaces.ts import type { InterfaceMap } from './interfaces'; type MappedType = { [K in keyof InterfaceMap]: Map<string, InterfaceMap[K]>; };
这样MappedType就会生成你预期的类型:
type MappedType = { Foo: Map<string, Foo>; Bar: Map<string, Bar>; Baz: Map<string, Baz>; };
额外说明
如果你的接口数量很多,手动维护InterfaceMap太麻烦,可以借助TypeScript的工具类型或者代码生成工具(比如ts-morph)来自动生成这个映射,避免重复劳动。
内容的提问来源于stack exchange,提问作者YSA
相关产品推荐
相关产品推荐

