为何使用`as`关键字映射类型会丢失文档注释?
问题:类型映射中使用
as关键字时保留属性文档注释 我从对象提取类型时,希望生成的类型属性保留原对象的JSDoc注释,但使用as关键字进行键过滤后,注释丢失了。以下是具体场景:
示例代码
原对象与类型定义
/** 用于提取类型的源对象 */ const obj = { /** 这是id属性的文档注释 */ id: undefined as string, /** 这是num属性的文档注释 */ num: 22 as number }; // 通过as关键字过滤值为string类型的属性 type UseAsKeyword<T> = { [K in keyof T as Extract<T[K], string> extends never ? never : K]: T[K]; }; // 直接映射所有属性的类型 type NoAsKeyword<T> = { [K in keyof T]: T[K] }; type ObjWithAs = UseAsKeyword<typeof obj>; type ObjNoAs = NoAsKeyword<typeof obj>;
使用时的注释差异
// hover时不显示原对象中id的注释 const testWithAs: ObjWithAs = { id: "hello" }; // hover时正常显示原对象中id和num的注释 const testNoAs: ObjNoAs = { id: "hello", num: 22 };
tsconfig.json配置
{ "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "Node", "allowSyntheticDefaultImports": true, "strictNullChecks": false } }
我需要实现:在使用as关键字进行键映射的同时保留属性文档注释;如果无法实现,求可保留注释的键映射替代方案。
解决方案
问题根源
截至TypeScript 5.x版本,使用映射类型的as子句时,TypeScript不会保留原始属性的JSDoc注释。这是因为as子句会生成新的键标识符,而非复用原键的元数据(包括注释)。
可行替代方案:Pick+条件类型过滤
如果需求是过滤符合条件的属性,可以通过Pick类型结合条件类型的方式实现,既能过滤属性又能保留注释:
// 过滤出值类型为string的属性 type FilterStringProperties<T> = Pick<T, { [K in keyof T]: T[K] extends string ? K : never }[keyof T]>; // 生成的类型保留原属性注释 type ObjFiltered = FilterStringProperties<typeof obj>;
验证效果
// hover时正常显示"这是id属性的文档注释" const testFiltered: ObjFiltered = { id: "hello" };
原理说明
Pick<T, K>类型直接从原类型T中选取指定键K,不会重新定义属性,因此会完整保留原属性的所有元数据(包括JSDoc注释)。内部的条件类型仅用于计算需要保留的键名列表,不会破坏原属性的结构。
其他场景说明
如果需要复杂的键转换(而非单纯过滤),目前TypeScript原生没有保留注释的解决方案。这种情况下可以:
- 尝试使用
type-fest等类型工具库的预定义工具类型; - 等待TypeScript后续版本对元数据保留的优化。
内容的提问来源于stack exchange,提问作者eslam sharif
相关产品推荐
相关产品推荐

