如何让值为特定类型的TypeScript对象保留智能提示?
实现带类型约束且保留智能提示的对象类型
当然可以实现,你之前的问题出在单独使用字符串索引签名会让TypeScript丢失对象的具体键信息,导致既没有智能提示,也无法正确识别你定义的具体属性。
核心思路
通过泛型捕获对象的具体键集合,同时约束所有键对应的值为指定类型,这样TypeScript既能保留键的具体名称用于智能提示,又能确保值的类型符合要求。
具体实现方案
方案1:使用工厂函数自动推断(推荐)
创建一个工厂函数,既约束值的类型,又让TypeScript自动推断对象的具体键:
function createTypedObject<T>(obj: Record<string, T>): typeof obj { return obj; } // 创建对象时指定值类型为number,TS会自动捕获prop1、prop2这些键 const TEST = createTypedObject<number>({ prop1: 123, prop2: 456 }); // 此时访问TEST.prop1会有智能提示,且值类型严格为number TEST.prop1 = 789; // 合法 TEST.prop1 = "abc"; // 编译报错,不符合number类型约束
方案2:泛型类型结合Record
直接定义泛型类型,手动指定键集合和值类型:
// K是对象的键类型,T是值类型 type ObjectWithValuesOf<T, K extends string | number | symbol> = Record<K, T>; // 明确指定键为'prop1'|'prop2',值类型为number const TEST: ObjectWithValuesOf<number, 'prop1' | 'prop2'> = { prop1: 123, prop2: 456 }; // 智能提示正常,类型约束生效 TEST.prop2; // 类型为number,有智能提示
方案3:泛型接口继承Record
如果偏好接口形式,可以让泛型接口继承Record来实现约束:
interface ObjectWithValuesOf<T, K extends string | number | symbol> extends Record<K, T> {} const TEST: ObjectWithValuesOf<number, 'prop1' | 'prop2'> = { prop1: 123, prop2: 456 };
为什么原来的方法不行?
你之前定义的ObjectWithKeysOf<T>只包含字符串索引签名[key: string]: T,这会让TypeScript认为该对象可以有任意字符串键,而不会保留你实际定义的prop1、prop2这些具体键的元信息,自然无法提供智能提示,甚至会因为TypeScript无法确认prop1是否符合索引签名的隐含规则而编译报错。
内容的提问来源于stack exchange,提问作者MadSkunk
相关产品推荐
相关产品推荐

