如何实现带映射返回类型的泛型设置工具并解决类型索引报错?
问题
我正尝试创建一个具备基础返回类型的泛型设置工具。应用将所有设置存储在一个集中式字典中,希望通过提供类型映射表来替代手动为每个键指定类型。
示例设置键映射:
const UserSettings = { DEFAULT_ORGANIZATION: 'user_profile.default_organization', THEME: 'user_profile.theme' } as const;
对应的类型映射表:
type UserSettingsTypes = { 'user_profile.default_organization': boolean; 'user_profile.theme': { primary: string; secondary: string }; };
期望编写的查询函数调用方式:
const organization = readSetting<UserSettingsTypes>(UserSettings.DEFAULT_ORGANIZATION);
其中organization能自动推导为boolean类型。
尝试的泛型定义:
const readSetting = <T extends Record<string, unknown>, K = keyof T>(key: K): T[K] => { // ... };
但编译器报错:Type 'K' cannot be used to index type 'T'
需要解决的问题:
- 是否可以实现这类映射返回类型?
- 如果可以,应如何构造
K以正确返回T中的映射类型?
解决方案
可以实现这种类型映射,问题出在泛型参数K的约束上。原来的写法中K = keyof T只是给了默认值,但没有明确约束K必须是T的键类型,导致TypeScript无法确认K能索引T。
基础正确实现
给K添加约束条件,让它必须是keyof T的子类型:
const readSetting = <T extends Record<string, unknown>, K extends keyof T>(key: K): T[K] => { // 实际逻辑示例:从集中式字典取值 return window.settingsStore[key] as T[K]; };
调用时TypeScript会自动推导返回类型:
// organization 类型自动推导为 boolean const organization = readSetting<UserSettingsTypes>(UserSettings.DEFAULT_ORGANIZATION); // theme 类型自动推导为 { primary: string; secondary: string } const theme = readSetting<UserSettingsTypes>(UserSettings.THEME);
简化写法
如果不需要单独复用K类型,可以省略显式声明,让TS自动推导键类型:
const readSetting = <T extends Record<string, unknown>>(key: keyof T): T[keyof T] => { return window.settingsStore[key] as T[keyof T]; };
强化类型安全(可选)
如果希望约束传入的key必须是UserSettings这类常量对象的取值,可以结合typeof进一步限制:
// 提取UserSettings的所有键值类型 type SettingKeys = typeof UserSettings[keyof typeof UserSettings]; const readSetting = <T extends Record<SettingKeys, unknown>>(key: SettingKeys): T[typeof key] => { return window.settingsStore[key] as T[typeof key]; };
这种写法下,若传入非UserSettings中的键,TypeScript会直接报错,避免无效键的传入。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

