在Typescript中如何解决链式动态对象属性赋值的类型报错问题
问题原因
你当前的类型定义不符合实际的数据结构,你把每个许可证对应的值定义为LicenseStatsCounter | LicenseStatsModules的联合类型,但实际上每个许可证条目是同时包含计数属性和依赖列表属性的单个对象,TS不知道你用titleUsedBy索引的时候拿到的是什么类型,自然会报索引不匹配的错误。
修正方案
首先调整接口定义,贴合你实际的结构:
// 把两个标题变量固定为字面量类型,方便TS做类型匹配 const titleUsageCount = 'Usage count' as const; const titleUsedBy = 'Used by' as const; // 单个许可证对应的条目类型 interface LicenseEntry { [titleUsageCount]: number; // Used by是可选属性,和你根据argv.summaryPlus动态生成的逻辑匹配 [titleUsedBy]?: Record<string, null>; } // 最终的licensesStats类型,key是许可证名称,value是上面的条目类型 interface LicensesStats { [key: string]: LicenseEntry; }
之后调整业务代码,可选属性赋值前做存在性判断,或者加断言告诉TS属性一定存在:
export const readLicenses = (argv: Argv) => { const licensesStats: LicensesStats = {}; const license = 'MIT'; const moduleNameAndVersion = 'chalk@1.0.0'; const enableSummaryPlus = argv.summaryPlus as boolean; licensesStats[license] = licensesStats[license] || { [titleUsageCount]: 0, ...(enableSummaryPlus && { [titleUsedBy]: {} }), }; licensesStats[license][titleUsageCount]++; // 先判断属性存在再赋值,不需要额外断言也能过TS校验 if (enableSummaryPlus && licensesStats[license][titleUsedBy]) { licensesStats[license][titleUsedBy][moduleNameAndVersion] = null; } };
如果你能保证执行到赋值逻辑时Used by属性一定存在,也可以直接用断言简化代码:
(licensesStats[license][titleUsedBy] as Record<string, null>)[moduleNameAndVersion] = null;
内容的提问来源于stack exchange,提问作者RSeidelsohn
相关产品推荐
相关产品推荐

