javascript - Indexerbar typ - TypeScript
Nedan syntax,
interface StringArray {
[index: number]: string;
}
anger att när en StringArray indexeras med ett number, kommer den att returnera en string. Till exempel -
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
Så, myArray är typbegränsad på värden som lagras som string-typ, genom att deklarera den med typen StringArray. Nyckeln(index) är alltid av string-typ, under huven (JavaScript), trots att den nämns som number
Från syntaxen nedan,
class Animal{
name: string;
}
class Dog extends Animal{
breed: string;
}
interface NotOkay {
[x: number]: Animal;
[x: string]: Dog;
}
- Vad anger
NotOkay-syntaxen?
Från syntaxen nedan,
interface NumberDictionary {
[index: string]: number;
length: number; // ok, length is a number
name: string; // error, the type of 'name' is not a subtype of the indexer
}
- Vad säger
NumberDictionary?
- Varför är dessa två syntax fel?
error TS2413&error: TS2411
Svar #1
(som @betadeveloper påpekar, är exemplen hämtade från TypeScript-dokumentationen på https://www.typescriptlang.org/docs/handbook/interfaces.html)
1+3) Poängen som dokumentationen gör är att denna deklaration inte är konsekvent.
Deklarationen verkar säga att denna kod fungerar:
let no: NotOkay
function byString(key: string): Dog {
return no[key]
}
function byNumber(key: number): Animal {
return no[key]
}
Men problemet är att en uppslagning av t.ex. no[0] egentligen är samma sak som no['0'] (det är så JavaScript fungerar). Så byString('0') kommer faktiskt bara att resultera i ett Djur, inte nödvändigtvis en Hund.
Så för att förhindra koden ovan - som ser korrekt ut men faktiskt är fel för vissa strängnycklar (de som råkar vara nummer i strängform) - tillåter inte TypeScript deklarationen.
2+3) [index: string]: number; säger att du kan använda vilken sträng som helst som ett index i ett NumberDictionary och du kommer att få ett nummer.
Å andra sidan säger name: string; att egenskapen name är en sträng. Men en egenskap kan också nås som ett index, så till exempel när man gör
let nd: NumberDictionary
let a = nd['name']
let b = nd.name
a och b betyder exakt samma sak, men den första deklarationen verkade säga att a var ett nummer, medan den andra deklarationen verkar säga att b är en sträng. Det är en motsägelse och därför är denna deklaration också inte tillåten.
