javascript - vilket är det bästa sättet att definiera ett objekt i typescript och komma åt dess värden?
Jag har ett objekt av format
export const IconSizeMap = {
'extra-small': '0.75rem',
small: '1rem',
medium: '1.5rem',
large: '2rem',
'extra-large': '4rem'
};
Eftersom jag är ny på TypeScript kunde jag inte förstå vad felet är
Det ger ett fel
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ 'extra-small': string; small: string; medium: string; large: string; 'extra-large': string; }'.
No index signature with a parameter of type 'string' was found on type '{ 'extra-small': string; small: string; medium: string; large: string; 'extra-large': string; }'.ts(7053)
när jag försöker använda
IconSizeMap[size]
Hur löser jag detta fel?
Svar #1
Du får detta fel eftersom din tsconfig.json har "noImplicitAny": true aktiverat. Det betyder att TypeScript kommer att leta efter och informera dig om ställen där du använder ett värde vars typ inte är känd, och där du inte uttryckligen har talat om för honom vilken typ det ska vara.
Dina lösningar för att bli av med det är antingen att:
- Inaktivera
noImplicitAnyi konfigurationen (Men jag antar att det finns en anledning till att det är här, så jag skulle inte rekommendera det) - Berätta för TypeScript typen av det du använder som orsakar felet.
Här kände TypeScript igen var och en av de 5 nycklarna du definierade (extra-small, small, medium, large och extra-large) eftersom du tilldelade dem ett värde som är en string, så den kan se att de är strängar. Dock är det endast dessa 5 strings som är nycklar.
När du använder en "generisk" string för att komma åt ditt objekt, såsom det jag antar att din size är, är du inte säker på om det motsvarar en av de 5 nycklarna. Så TypeScript varnar dig för det.
En lösning på det kan vara att berätta för kompilatorn att du är säker på vad du gör, och specificera typen av size mer exakt. Till exempel :
export const IconSizeMap = {
'extra-small': '0.75rem',
small: '1rem',
medium: '1.5rem',
large: '2rem',
'extra-large': '4rem'
};
let size: keyof typeof IconSizeMap; // Means "I'm sure that size is one of those strings
size = "small";
console.log(IconSizeMap[size]);
Lekplatslänk
Svar #2
IconSizeMap[size] försöker använda en sträng som ett index på ett objekt som inte är definierat med strängindexering, vilket är anledningen till att du får det felet.
Dina alternativ är:
Lägg till en strängindexsignatur till objektet, eller
Använd inte en generell sträng för att indexera i objektet
Vad du gör beror på ditt användningsfall. En indexsignatur betyder att TypeScript inte proaktivt kan kontrollera för dig att size matchar en egenskap på objektet. Men att använda endast specifika egenskapsnamn innebär att lista dessa egenskapsnamn på mer än ett ställe om din startpunkt är en sträng som kan ha vilket värde som helst.
Här är ett exempel på #1:
export const IconSizeMap: {[key: string]: string} = {
// −−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^
'extra-small': '0.75rem',
small: '1rem',
medium: '1.5rem',
large: '2rem',
'extra-large': '4rem'
};
Lekplatslänk
Här är ett exempel på #2:
function getIconSize(size: string) {
switch (size) {
case 'extra-small':
return IconSizeMap['extra-small'];
case 'small':
return IconSizeMap.small;
case 'medium':
return IconSizeMap.medium;
case 'large':
return IconSizeMap.large;
case 'extra-large':
return IconSizeMap['extra-large'];
default:
throw new Error(`Invalid 'size' for IconSizeMap: ${size}`);
}
}
Observera hur vi använder specifika strängliteral, inte bara vilken sträng som helst, när vi går åt objektet.
Lekplatslänk
