我正在切换一个JS项目到TS,我正在努力与我的代码的某一部分,TS抱怨,我不知道如何解决这个问题。
在TS中,我想在一个名为licensesStats
的动态对象中收集数据,最终可能看起来像这样:
{
'DYNAMIC_NAME': {
'Usage count': 2,
'Used by': {
'SOME_DYNAMIC_NAME': null,
'SOME_OTHER_NAME': null,
[...]
}
},
[...]
}
对于我的licensesStats
对象,我创建了以下interface
:
interface LicenseStatsCounter {
[key: string]: number;
}
interface LicenseStatsModule {
[key: string]: null;
}
interface LicenseStatsModules {
[key: string]: LicenseStatsModule;
}
interface LicensesStats {
[key: string]:
| LicenseStatsCounter
| LicenseStatsModules;
}
licensesStats: LicensesStats = {}
...
键"使用量"one_answers"使用;都存储在变量中,因此在数据收集期间的代码中,有这样一个命令:
licensesStats[license][titleUsedBy][moduleNameAndVersion] = null;
但TS抱怨:
元素隐式地具有'any'类型,因为type的表达式'string'不能用于索引类型'number | LicenseStatsModule'。
在类型上没有找到带有'string'类型参数的索引签名'number | LicenseStatsModule'.
我该怎么做才能满足TypeScript的需求?
注:以下是我的问题的示例TS文件:
const titleUsageCount = 'Usage count';
const titleUsedBy = 'Used by';
interface LicenseStatsCounter {
[key: string]: number;
}
interface LicenseStatsModule {
[key: string]: null;
}
interface LicenseStatsModules {
[key: string]: LicenseStatsModule;
}
interface LicensesStats {
[key: string]: LicenseStatsCounter | LicenseStatsModules;
}
// Exported functions:
export const readLicenses = (argv: Argv) => {
const licensesStats: LicensesStats = {};
const license = 'MIT';
const moduleNameAndVersion = 'chalk@1.0.0';
licensesStats[license] = licensesStats[license] || {
[titleUsageCount]: 0,
...((argv.summaryPlus as boolean) && { [titleUsedBy]: {} }),
};
(licensesStats[license][titleUsageCount] as number)++;
// This is the problematic line, where TS says:
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'number | LicenseStatsModule'.
// No index signature with a parameter of type 'string' was found on type 'number | LicenseStatsModule'.
licensesStats[license][titleUsedBy][moduleNameAndVersion] = null;
}
};
在当前的设置下,typescript到达licensesStats[license][titleUsedBy]
并看到两个可能的值:number
或object
(LicenseStatsModule)并抛出错误,因为数字不能包含属性。
你将需要一些条件检查来使typescript满意,比如:
const x = licensesStats[license][titleUsedBy];
if(typeof x !== "number"){
const y = x[moduleNameAndVersion];
// ... do something
return;
}
// ... do something
return;