'Eigenschaft existiert nicht für Typ' nie '

77

Dies ist ähnlich wie # 40796374, aber das sind Typen, während ich Schnittstellen verwende.

Angesichts des folgenden Codes:

interface Foo {
  name: string;
}

function go() {
  let instance: Foo | null = null;
  let mutator = () => {
   instance = {
     name: 'string'
   };  
  };

  mutator();

  if (instance == null) {
   console.log('Instance is null or undefined');
  } else {
   console.log(instance.name);
  }
}

Ich habe eine Fehlermeldung, dass der Name 'Eigenschaft' für den Typ 'Nie' nicht vorhanden ist.

Ich verstehe nicht, wie eine Instanz jemals ein "Niemals" sein könnte. Kann jemand etwas Licht ins Dunkel bringen?

Danke im Voraus.

Ray Booysen
quelle
8
Aus Ihrem Code geht ziemlich klar hervor, dass das elsetatsächlich niemals ausgewertet werden würde. Der Compiler ist klug genug, um es zu sehen.
Nitzan Tomer
Dies ist ein Beispiel. Lassen Sie mich weiteren Code hinzufügen, der zeigt, dass das Problem weiterhin besteht.
Ray Booysen
9
It's pretty clear from your code that the else would indeed never get evaluated.Es ist überhaupt nicht offensichtlich und es gibt auch keinen intelligenten Compiler. Es gibt einen dummen Transpiler, der von den etablierten Praktiken abweicht. In C # kann man nullzum Beispiel jedem Objekt zuweisen ...
Bozhidar Stoyneff

Antworten:

57

Da Sie die Zuordnung instancezu null. Der Compiler schließt daraus, dass es niemals etwas anderes sein kann als null. Es wird also davon ausgegangen, dass der else-Block niemals ausgeführt werden sollte und daher instancewie neverim else-Block eingegeben wird .

Wenn Sie es nun nicht als Literalwert deklarieren nullund auf andere Weise abrufen (z. B. :) let instance: Foo | null = getFoo();, sehen Sie, dass instancees sich nullim if-Block und Fooim else-Block befindet.

Geben Sie niemals Dokumentation ein: https://www.typescriptlang.org/docs/handbook/basic-types.html#never

Bearbeiten:

Das Problem im aktualisierten Beispiel ist tatsächlich ein offenes Problem mit dem Compiler. Sehen:

https://github.com/Microsoft/TypeScript/issues/11498 https://github.com/Microsoft/TypeScript/issues/12176

Saravana
quelle
Danke @saravana. Ich habe das Beispiel mit einem Abschluss aktualisiert, von dem ich gehofft hätte, dass der Compiler ihn aufgreifen würde. Entschuldigung, ich hätte das zuerst hinzufügen sollen.
Ray Booysen
Sieht nach einem offenen Problem mit dem Compiler aus. Siehe die folgenden Probleme: github.com/Microsoft/TypeScript/issues/11498 github.com/Microsoft/TypeScript/issues/12176
Saravana
Es gibt auch ein anderes Problem insgesamt, das einen ähnlichen "falschen" Fehler erzeugt github.com/Microsoft/TypeScript/issues/10570
Olga
23

Wenn Sie Component als React.FC schreiben und useState () verwenden,

Schreiben Sie einfach so wäre hilfreich:

const [arr, setArr] = useState<any[]>([])
blaue Hoffnung
quelle
Vielen Dank. Ich würde sagen, dies ist die beste Lösung für dieses Problem.
Eliaquin
Dies löste mein Problem, bei dem ich arras keinen Typ zuweisen kann arr: any.
cst1992
16

Dies scheint diesem Problem ähnlich zu sein: Falsch "Eigenschaft existiert nicht für Typ 'nie'", wenn der Wert innerhalb des Rückrufs mitstrictNullChecks geändert wird. Dies wird als Duplikat dieses Problems geschlossen (Diskussion): Kompromisse bei der Kontrollflussanalyse .

Diese Diskussion ist ziemlich lang. Wenn Sie dort keine gute Lösung finden, können Sie Folgendes versuchen:

if (instance == null) {
    console.log('Instance is null or undefined');
} else {
    console.log(instance!.name); // ok now
}
Nitzan Tomer
quelle
Danke @Nitzan. Genau das mache ich in meinem Code
Ray Booysen
In einigen Situationen habe ich immer noch den gleichen Fehler erhalten, auch wenn ich diese Methode verwende, so etwas wie a!.b!.cund habe das gesagt Property c ....
Tokenyet
10

Ich hatte den gleichen Fehler und ersetzte die Punktnotation durch die Klammernotation, um sie zu unterdrücken.

zB: obj.name -> obj ['name']

Eric Grotke
quelle
Ist das ein Fehler? arbeitete auch für mich. Warum sollte die Punktnotation nicht funktionieren?
wrod7
0

Wenn Sie den Fehler im Parameter erhalten, behalten Sie die Eingabe anyoder den any[]Typ der Eingabe wie unten

getOptionLabel={(option: any) => option!.name}
 <Autocomplete
    options={tests}
    getOptionLabel={(option: any) => option!.name}
    ....
  />
Code
quelle