Typescript: Die Typprüfung verliert die Eingabe für

Erstellt am 8. Nov. 2016  ·  3Kommentare  ·  Quelle: microsoft/TypeScript

TypeScript-Version: 2.0.8

Code

// test.ts
interface Type {
  type: number;
}

interface TypeExt extends Type {
  arr: Type[];
}

const guard = (arg: Type): arg is TypeExt => arg.type === 1;
const otherFunc = (arg1: Type, arg2: TypeExt): void => {};

export function y(arg: Type): void {
  if (guard(arg)) {
    for (const ITEM/* error is here */ of arg.arr) {
      if (otherFunc(ITEM, arg)) {
      }
    }
  }
}

Kompiliert mit cmd: tsc --noImplicitAny test.ts

Erwartetes Verhalten:
Keine Fehler

Tatsächliches Verhalten:

test.ts(14,16): error TS7022: 'ITEM' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Bug Fixed

Hilfreichster Kommentar

Dies ist ein Problem bei der Kontrollflussanalyse. Um einen Typ für ITEM abzuleiten, müssen wir den Kontrollflusstyp von arg.arr herausfinden. Das bedeutet wiederum, dass wir uns Konstrukte ansehen müssen, die sich auf den Typ von arg auswirken. Dies schließt den Aufruf von otherFunc der so aussieht, als ob es sich um ein benutzerdefiniertes Prädikat handeln könnte. Um festzustellen, ob es sich um ein Typprädikat handelt, lösen wir den Aufrufausdruck auf, bei dem die Argumentausdrücke aufgelöst werden. Dazu müssen wir den Typ von ITEM . Dies erzeugt eine Zirkularität, die wir nicht auflösen können, sodass wir auf einen impliziten any -Typ zurückgreifen.

Wir können dies beheben, indem die Erkennungslogik für Typprädikate zuerst den Typ des Funktionsobjekts auflöst und alle Aufrufsignaturen untersucht. Wenn es sich bei keinem von ihnen um benutzerdefinierte Prädikate handelt, können wir frühzeitig aussteigen, ohne die Aufrufargumentausdrücke aufzulösen, wodurch die Zirkularität vermieden wird.

In der Zwischenzeit können Sie die Zirkularität einfach durch Hinzufügen von Klammern zu arg im Aufruf von otherFunc durchbrechen. Mit anderen Worten, ändern Sie den Anruf in otherFunc(ITEM, (arg)) . Dies führt dazu, dass der Kontrollflussanalysator den Aufruf nicht mehr als möglichen benutzerdefinierten Prädikataufruf vom Typ betrachtet.

Alle 3 Kommentare

Dies ist ein Problem bei der Kontrollflussanalyse. Um einen Typ für ITEM abzuleiten, müssen wir den Kontrollflusstyp von arg.arr herausfinden. Das bedeutet wiederum, dass wir uns Konstrukte ansehen müssen, die sich auf den Typ von arg auswirken. Dies schließt den Aufruf von otherFunc der so aussieht, als ob es sich um ein benutzerdefiniertes Prädikat handeln könnte. Um festzustellen, ob es sich um ein Typprädikat handelt, lösen wir den Aufrufausdruck auf, bei dem die Argumentausdrücke aufgelöst werden. Dazu müssen wir den Typ von ITEM . Dies erzeugt eine Zirkularität, die wir nicht auflösen können, sodass wir auf einen impliziten any -Typ zurückgreifen.

Wir können dies beheben, indem die Erkennungslogik für Typprädikate zuerst den Typ des Funktionsobjekts auflöst und alle Aufrufsignaturen untersucht. Wenn es sich bei keinem von ihnen um benutzerdefinierte Prädikate handelt, können wir frühzeitig aussteigen, ohne die Aufrufargumentausdrücke aufzulösen, wodurch die Zirkularität vermieden wird.

In der Zwischenzeit können Sie die Zirkularität einfach durch Hinzufügen von Klammern zu arg im Aufruf von otherFunc durchbrechen. Mit anderen Worten, ändern Sie den Anruf in otherFunc(ITEM, (arg)) . Dies führt dazu, dass der Kontrollflussanalysator den Aufruf nicht mehr als möglichen benutzerdefinierten Prädikataufruf vom Typ betrachtet.

@ahejlsberg
Vielen Dank für die Problemumgehung in Klammern.
Ich möchte das herausfinden. PR ist akzeptabel, nicht wahr?

@arusakov Jetzt im Master

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

weswigham picture weswigham  ·  3Kommentare

dlaberge picture dlaberge  ·  3Kommentare

uber5001 picture uber5001  ·  3Kommentare

CyrusNajmabadi picture CyrusNajmabadi  ·  3Kommentare

manekinekko picture manekinekko  ·  3Kommentare