我有这个复杂的物体
const classes = {
Barbarian: {
armorAndWeoponProficianies: [
'lightAmour',
'mediumArmour',
'Sheilds',
'simpleWeopons',
'martialWeopons',
],
class: 'Barbarian',
description:
'A fierce warrior of primitive background who can enter a battle rage',
hitDie: '1d12',
primaryAbility: 'STR',
savingThrowProficianies: ['STR', 'CON'],
},
Bard: {
armorAndWeoponProficianies: [
'lightArmor',
'simpleWeapons',
'handCrossbows',
'longswords',
'rapiers',
'shortswords',
],
class: 'Bard',
description:
'An inspiring magician whose power echoes the music of creation',
hitDie: '1d8',
primaryAbility: 'CHA',
savingThrowProficianies: ['DEX', 'CHA'],
},
}
在这里,我想使用参数classType作为键,但是TypeScript不喜欢它
const hitPointGenerator = (classType: string) => {
const selectedClass = classes[classType].hitDie;
// ^ Error
console.log(selectedClass)
};
我得到的错误是
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ Barbarian: { armorAndWeoponProficianies: string[]; class: string; description: string; hitDie: string; primaryAbility: string; savingThrowProficianies: string[]; }; Bard: { armorAndWeoponProficianies: string[]; ... 4 more ...; savingThrowProficianies: string[]; }; ... 9 more ...; Wizzard: { ...; }; }'.
No index signature with a parameter of type 'string' was found on type '{ Barbarian: { armorAndWeoponProficianies: string[]; class: string; description: string; hitDie: string; primaryAbility: string; savingThrowProficianies: string[]; }; Bard: { armorAndWeoponProficianies: string[]; ... 4 more ...; savingThrowProficianies: string[]; }; ... 9 more ...; Wizzard: { ...; }; }'.ts(7053)
答案 0 :(得分:3)
有多种解决方法:
将classType
参数更改为keyof typeof classes
const hitPointGenerator = (classType: keyof typeof classes) => {
const selectedClass = classes[classType].hitDie;
console.log(selectedClass)
};
这样的优点是您不会意外地用错误的键来调用它,例如
hitPointGenerator('Bard'); // OK
hitPointGenerator('Bart'); // compile error - notice the 't' at the end
当您将鼠标悬停在typescript-playground的classType
参数上时,您会看到类型为"Barbarian" | "Beard"
:这是Union Type,在这种情况下为{{1 }}(即更具体)
string
使用此字符串索引签名,您可以将新项目动态添加到const classes: {
[key: string]: any;
} = {
Barbarian: {
...
对象:
classes
有关index-signature的更多信息
要同时使用值的类型,可以定义一个接口,例如:
classes['new'] = {
...
}
interface IMember {
armorAndWeoponProficianies: string[];
class: string;
description: string;
hitDie: string;
primaryAbility: string;
savingThrowProficianies: string[];
}
// we use an index signature to tell typescript that keys of type string are allowed
const classes: {
[key: string]: IMember;
} = {
...
}
这仅仅是为了完成:我会避免这种情况。
在 const hitPointGenerator3 = (classType: string) => {
const selectedClass = (classes as any)[classType].hitDie;
// ^ cast
console.log(selectedClass)
};
-ref
noImplicitAny
选项
当您将一些javascript代码迁移到打字稿时,这可能会很有用:我不会将其用于新项目,并尽可能尝试激活tsconfig.json
答案 1 :(得分:2)
之所以发生这种情况,是因为classes
只有两个有效键,但是字符串实际上可以是任何字符串。
也许尝试将函数签名更改为;
const hitPointGenerator = (classType: keyof typeof classes) => {
const selectedClass = classes[classType].hitDie;
console.log(selectedClass)
};
这样只有"Barbarian" | "Bard"
是classType的有效输入