泛型约束:确保T所有属性类型一致及对象类型转换问题
解决方案
你的核心需求是确保输入对象的每个属性都符合{ default: boolean, name: string, desc: string }结构,输出对象与输入键完全一致,每个属性值为boolean。当前代码存在返回值类型不匹配、泛型约束未严格生效的问题,以下是修正方案:
1. 修复返回值类型不匹配问题
当前代码中ret是Partial<SettingsReturnType<T>>类型,无法直接赋值给Promise<SettingsReturnType<T>>。你可以通过遍历输入对象的所有键来填充返回值,再通过类型断言确保类型正确:
export type SettingsArgType = { [key: string]: { default: boolean, name: string, desc: string } }; export type SettingsReturnType<T extends SettingsArgType> = { [key in keyof T]: boolean; }; export async function settingsHelper<T extends SettingsArgType>(options: T): Promise<SettingsReturnType<T>> { const ret: Partial<SettingsReturnType<T>> = {}; // 遍历输入对象,用每个属性的default值初始化返回对象 for (const key in options) { ret[key] = options[key].default; } // 断言为完整类型,因为已遍历所有键完成赋值 return ret as SettingsReturnType<T>; }
2. 强化泛型约束(可选)
如果希望严格限制输入对象的属性只能包含default、name、desc三个字段(不允许额外属性),可以自定义Exact类型实现严格结构检查:
// 定义Exact类型,确保输入类型没有额外属性 type Exact<T, U> = T extends U ? (U extends T ? T : never) : never; export type SettingsProp = { default: boolean, name: string, desc: string }; export type SettingsArgType = { [key: string]: SettingsProp }; export type SettingsReturnType<T extends SettingsArgType> = { [key in keyof T]: boolean; }; // 使用Exact约束输入必须严格匹配SettingsArgType结构 export async function settingsHelper<T extends SettingsArgType>( options: Exact<T, SettingsArgType> ): Promise<SettingsReturnType<T>> { const ret: Partial<SettingsReturnType<T>> = {}; for (const key in options) { ret[key] = options[key].default; } return ret as SettingsReturnType<T>; }
此时传入带额外属性的对象会直接报错:
// 错误:类型"{ darkMode: { default: boolean; name: string; desc: string; extra: number; }; }"不满足Exact约束 settingsHelper({ darkMode: { default: true, name: 'Dark Mode', desc: 'Enable dark theme', extra: 123 } });
3. 验证约束生效
调用函数时,若传入不符合结构的属性,TypeScript会立即提示错误:
// 错误:属性"desc"在类型"{ default: true; name: string; }"中缺失 settingsHelper({ darkMode: { default: true, name: 'Dark Mode' } }); // 错误:类型"number"不能赋值给类型"boolean" settingsHelper({ darkMode: { default: 123, name: 'Dark Mode', desc: 'Enable dark theme' } });
内容的提问来源于stack exchange,提问作者kinderhead
相关产品推荐
相关产品推荐

