Array.reduce中无法分配原始类型值的TypeScript报错疑问
问题分析与解决
错误原因
你遇到的TypeScript错误,核心是泛型约束的类型兼容性问题:
- 泛型
Obj被定义为extends Record<string, boolean>,这意味着Obj的属性值可以是更具体的布尔字面量类型(比如true或false,而非宽泛的boolean)。 arrayOfIncluded.includes(cur)返回的是标准boolean类型,TypeScript认为这个宽泛类型无法安全赋值给Obj[keyof Obj](后者可能是严格的字面量类型),因此抛出类型不兼容错误。
举个实际场景:如果传入的boolFramework是类型为{ apple: false; banana: false }的对象,那么Obj[keyof Obj]就是false字面量类型,而你要赋值的true/false是boolean类型,两者在严格类型检查中不匹配。
解决方案
以下是几种简洁可行的解决方式:
方案1:类型断言明确赋值类型
直接通过类型断言告诉TypeScript,当前赋值的类型与Obj[keyof Obj]兼容:
// Helper function to type Object.Keys const objectKeysTyped = <Obj extends object>(obj: Obj) => { return Object.keys(obj) as (keyof Obj)[]; }; // Main function const arrayToBoolIndicator = <Obj extends Record<string, boolean>>( boolFramework: Obj, arrayOfIncluded: (keyof Obj)[] ) => { return objectKeysTyped(boolFramework).reduce( (acc, cur) => { acc[cur] = arrayOfIncluded.includes(cur) as Obj[keyof Obj]; return acc; }, { ...boolFramework } ); };
方案2:明确初始值的类型为宽泛boolean
如果不需要保留原始对象的布尔字面量类型,可以将reduce的初始值类型强制转为宽泛的布尔值对象:
// Helper function to type Object.Keys const objectKeysTyped = <Obj extends object>(obj: Obj) => { return Object.keys(obj) as (keyof Obj)[]; }; // Main function const arrayToBoolIndicator = <Obj extends Record<string, boolean>>( boolFramework: Obj, arrayOfIncluded: (keyof Obj)[] ) => { return objectKeysTyped(boolFramework).reduce( (acc, cur) => { acc[cur] = arrayOfIncluded.includes(cur); return acc; }, { ...boolFramework } as Record<keyof Obj, boolean> ); };
方案3:用Object.fromEntries简化实现
抛弃reduce写法,用更简洁的Object.fromEntries实现,同时规避类型问题:
const arrayToBoolIndicator = <Obj extends Record<string, boolean>>( boolFramework: Obj, arrayOfIncluded: (keyof Obj)[] ) => { const includedSet = new Set(arrayOfIncluded); return Object.fromEntries( Object.keys(boolFramework).map(key => [ key, includedSet.has(key as keyof Obj) ]) ) as Obj; };
内容的提问来源于stack exchange,提问作者edishu
相关产品推荐
相关产品推荐

