如何控制TypeScript类型悬停提示(tooltip)提升实用性?
TypeScript类型悬停提示控制方案
核心结论
可以完全自定义控制TypeScript的类型悬停提示展示内容,且不会改变类型的实际推导逻辑、不影响类型安全。
问题成因
TypeScript默认的悬停提示不会主动展开所有类型别名,当类型定义中引用了内部辅助类型时,提示会直接保留这些别名的名称和泛型参数(比如示例中显示的[DontShowThisRedundantType<()=>string,string>]),而非展示最终推导的结构类型,导致提示冗余、可读性差。
具体实现方式
利用TypeScript对映射类型、条件类型的强制计算规则,定义通用的类型展开工具类型,在对外暴露的最终类型出口处包裹内部辅助类型,即可强制TS计算并展示最终的类型结构,隐藏内部实现用的辅助类型。
基础版展开工具(适配绝大多数场景)
/** * 强制展开类型,优化悬停提示 * 单独适配函数类型,避免被映射为对象结构 */ type Prettify<T> = T extends (...args: infer Args) => infer R ? (...args: Args) => R : { [K in keyof T]: T[K] }
示例改造
针对上述示例场景,只需要在对外暴露的FnSwappedToArrray类型中,用Prettify包裹内部辅助类型即可:
type DontShowThisRedundantType<T, R = T extends ()=>infer X ? X : never> = (arg: R)=>void // 对外类型出口处包裹Prettify,强制展开内部类型 type FnSwappedToArrray<T extends ()=>any> = [Prettify<DontShowThisRedundantType<T>>] // 此时悬停查看A的类型,会直接显示目标结果:[(arg: string) => void] type A = FnSwappedToArrray<()=>string>
递归版展开工具(适配深层嵌套复杂类型)
如果类型嵌套层级很深,可以使用递归版本的工具,深层展开所有嵌套的类型结构:
type DeepPrettify<T> = T extends (...args: infer Args) => infer R ? (...args: DeepPrettify<Args>) => DeepPrettify<R> : T extends Array<infer U> ? Array<DeepPrettify<U>> : T extends object ? { [K in keyof T]: DeepPrettify<T[K]> } : T
注意事项
- 该方案仅修改编辑器的类型提示展示,完全不改变类型的实际校验、推导逻辑,无类型安全风险
- 仅需要在对外暴露给使用者的最终类型出口处使用展开工具即可,不要在内部辅助类型上层层包裹,避免增加不必要的类型计算开销
- 针对联合类型、元组、Promise等特殊类型,可以根据实际使用场景在Prettify工具中补充对应的判断分支,保证展开后类型语义和原类型完全一致
内容的提问来源于stack exchange,提问作者TrevTheDev
相关产品推荐
相关产品推荐

