我在一个.tsx文件中工作,对TS/Rect完全陌生。我正试图在StringMap的第一个索引处添加一个键/值对。
我下面有一些代码:
接收StringMap"stats",
遍历每一行并从字符串中提取氏族,
将每个氏族添加到"氏族"(字符串[](,
使用氏族的创建一个新的统计地图
function handlePlayerStatssWindow(stats: StringMap<string>)
{
const rawFields = Object.keys(stats).map((key, i) => (
<div key={i}>
{key}: {stats[key]}
</div>
));
var clans: string[] = [];
for (const [key, value] of Object.entries(stats))
{
const roles: string[] = value.split(',');
for(const role of roles)
{
if(role.includes('clan='))
{
clans.push(role.replace('clan=',''));
}
}
}
const statsWithClans = {...stats};
statsWithClans.clans = clans.toString();
// const statsWithClans = {clans: (clans.toString()), ...stats};
const formattedFields = Object.keys(statsWithClans).map((key, i) => (
<div key={i}>
{key}: {statsWithClans[key]}
</div>
));
}
代码的工作和输出类似于:
Name: Jeff
Class: Mage
Clans: Clan1, Clan2
如果我一开始就尝试创建带有部族的地图,就像一样
const statsWithClans={clans:(clans.toString(((,…stats};
Typescript抱怨说:
元素隐式具有"any"类型,因为"string"类型的表达式不能用于索引类型"{groups:string;}"。在类型"{groups:string;}"上找不到具有"string"类型参数的索引签名。ts(7053(
和"statsWithClans[key]"突出显示
字符串映射定义
export default interface StringMap<T> {
[index: string]: T;
}
这是TypeScript中的一个已知问题,请参阅microsoft/TypeScript#227273。如果确实将具有索引签名的对象扩展为具有其他属性的对象文字,则编译器会静默地丢弃索引签名。由于您的StringMap<T>
类型有一个索引签名,这就是发生的情况:
const oops = { clans: (clans.toString()), ...stats };
// const oops: { clans: string; }
stats
上的索引签名被遗忘,新变量的类型为{clans: string}
,没有索引签名。并且,除非某个值具有字符串索引签名,否则不能使用任意的string
键对该值进行索引。
在示例代码中处理此问题的最简单方法是显式注释stats
变量的类型:
const statsWithClans: StringMap<string> =
{ clans: (clans.toString()), ...stats }; // okay
现在statsWithClans
是所期望的类型,并且您的代码的其余部分按照期望的方式运行:
const formattedFields = Object.keys(statsWithClans).map((key, i) => (
<div key={i}>
{key}: {statsWithClans[key]} // okay
</div>
));
游乐场链接到代码