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;   
}
  1. 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
}
  1. Vad säger NumberDictionary?

  1. 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.

Relaterade artiklar