Typescript: Die Indexsignatur fehlt im Typ

8

Ich möchte MyInterface.dic wie ein Wörterbuch name: value haben, ich definiere es wie folgt:

%Vor%

Jetzt erstelle ich eine Funktion, die auf meinen Typ wartet:

%Vor%

Und die Eingabe:

%Vor%

Ich erwarte, dass foo(o) korrekt ist, aber der Compiler fällt:

%Vor%

Ich weiß, dass es ein mögliches Casting gibt: let o: MyInterface = { ... } , das den Trick macht, aber die Frage ist, warum Typoskript meinen Typ nicht erkennt?

Extra: funktioniert gut, wenn o inline deklariert ist:

%Vor%     
Manu 03.05.2016, 13:45
quelle

1 Antwort

10

Das Problem ist, dass, wenn der Typ abgeleitet wird, der Typ von o lautet:

%Vor%

Das ist nicht dasselbe wie { dic: { [name: string]: number } } . Kritisch, mit der Top-Signatur darf man nicht so etwas wie o.dic['x'] = 1 machen. Mit der 2. Unterschrift bist du.

Sie sind zur Laufzeit äquivalente Typen (in der Tat, sie sind genau der gleiche Wert), aber ein großer Teil der Sicherheit von TypeScript kommt von der Tatsache, dass diese nicht die gleichen sind und dass Sie nur eine davon behandeln lassen Objekt als ein Wörterbuch, wenn es weiß, dass es explizit als eins beabsichtigt ist. Dies verhindert, dass Sie versehentlich nicht vorhandene Eigenschaften von Objekten lesen und schreiben.

Die Lösung besteht darin, sicherzustellen, dass TypeScript weiß, dass es als Wörterbuch gedacht ist. Das heißt:

  • Geben Sie explizit einen Typ an, der besagt, dass es sich um ein Wörterbuch handelt:

    let o: MyInterface

  • Setzen Sie es als Inline-Wörterbuch fort:

    let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }

  • Stellen Sie sicher, dass es der ursprüngliche Typ ist, den TypeScript für Sie bestimmt:

    foo({ dic: { 'a': 1, 'b': 2 } })

Wenn TypeScript denkt, dass es ein normales Objekt mit nur zwei Eigenschaften ist und Sie es später als Wörterbuch verwenden wollen, ist es unglücklich.

    
Tim Perry 03.05.2016, 13:52
quelle

Tags und Links