TypeScript类型推断:如何让TS自动提示对象属性生成的方法名?
解决方案
问题出在你用Selectors索引签名约束传入的selectors,导致TypeScript丢失了对象的具体键名信息,只能识别通用命名模式,无法推断出精确的成员。要解决这个问题,需要通过泛型保留传入对象的具体类型信息:
1. 调整类型定义
修改GettersWithUniqueName和generateGetDOMElements的类型,用泛型捕获传入对象的具体键:
interface Selector { findBy: (id: string, options?: any) => any; id: string; } // 保留Selectors接口但不再用于参数约束 export interface Selectors { [key: string]: Selector; } // 基于泛型T的具体键生成get方法类型 type GettersWithUniqueName<T extends Record<string, Selector>> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => any; }; // 用泛型T捕获传入selectors的具体类型 declare const generateGetDOMElements: <T extends Record<string, Selector>>(selectors: T) => () => GettersWithUniqueName<T>;
2. 修改使用方式
不要给selectors标注Selectors类型,让TypeScript自动推断它的具体结构:
const selectors = { element1: { findBy: () => {}, id: '' }, element2: { findBy: () => {}, id: '' } }; const elements = generateGetDOMElements(selectors); const getters = elements(); // 此时TypeScript会准确提示getters只有getElement1和getElement2两个方法 getters.getElement1(); // 正常 getters.getElement2(); // 正常 getters.getBob(); // 类型报错,符合预期
原理说明
- 泛型
T会完整保留传入selectors对象的键名和类型信息,不会被索引签名抹平。 Capitalize<string & K>确保只有字符串类型的键能参与命名转换,避免类型错误。- 去掉
selectors的Selectors标注后,TypeScript能自动推断出对象的具体成员,进而让GettersWithUniqueName生成精确的方法类型。
内容的提问来源于stack exchange,提问作者Emiliano Morghen
相关产品推荐
相关产品推荐

