2017-12-27 3 views
2

Auch bei basarat Erläuterungen zu Art Behauptungen in seinem großen Buch TypeScript Deep Dive:Detaillierte Unterschiede zwischen Typenannotation `Variable: Baumuster zur und Art Behauptung` Ausdruck als Baumuster zur in Typoskript

Grundsätzlich ist die Behauptung von Typ S zu T gelingt, wenn entweder S ist ein Subtyp T oder T ist ein Untertyp von S.

Ich habe mich gefragt, was zwischen Typenannotation variable: type und Typ Behauptung expression as type, genauer gesagt der genauen Unterschied ist, wenn Typ Behauptung funktioniert oder nicht, vor allem in Bezug auf diesen Typoskript Fehler sind manchmal überraschend: sehen, wie sie für das foo3 und foo5 Variablen unten:

interface Foo { 
    n?: number; 
    s: string; 
} 

const foo1 = {} as Foo;    // ok 
const foo2 = { n: 1 } as Foo;   // ok 
const foo3 = { n: '' } as Foo;  // KO: "Property 's' is missing..." 
const foo4 = { n: '' as any } as Foo; // ok 
const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..." 
const foo6 = { s: '', x: 2 } as Foo; // ok 
const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible." 

Andere Unterschied, den ich bemerkt habe: die n Eigenschaft in der Foo Schnittstelle in VSCode Umbenennung propagieren nicht auf Ausdrücke behauptet wird, während es mit dem Typ arbeitet kommentierten Variablen.

+0

Dies ist interessant, weil es Fehler aus, wenn Sie den falschen Typs für eine Eigenschaft zur Verfügung stellen, aber die Fehlermeldung ist immer über eine andere Eigenschaft. Abgesehen davon, wenn die von Ihnen bereitgestellten Eigenschaftsnamen vom richtigen Typ sind, können andere Eigenschaften weggelassen oder hinzugefügt werden, was sinnvoll erscheint. –

Antwort

2

Ich habe mich gefragt, was zwischen Typenannotation variable: type und Typ Behauptung Ausdruck als Typ

Typdeklaration variable: type teilt dem Compiler mit, dass die Variable muss immer entsprechen dem deklarierten Typ der genaue Unterschied ist. Es wird von typechecker verwendet, wenn der Variablen ein Wert zugewiesen wird (der Wert muss mit dem deklarierten Typ kompatibel sein), und auch immer dann, wenn die Variable verwendet wird (der deklarierte Typ der Variablen muss mit der Art und Weise kompatibel sein, in der die Variable verwendet wird) jeder bestimmte Ort).

Die Typassertion überschreibt die integrierten Kompatibilitätsregeln. Sie können dem Compiler mitteilen, dass Sie wissen, dass der Wert tatsächlich dem Typ entspricht, den Sie in der Assertion angeben, und somit die Fehlermeldung über die Typinkompatibilität unterdrücken. Es gibt jedoch Grenzen - Sie können nicht einfach behaupten, dass die Variable einen beliebigen Typ hat (BTW gibt es any Typ nur dafür). Wie Sie in der Frage zitiert, für Typen Behauptung zu arbeiten,

die Behauptung vom Typ S zu T ist erfolgreich, wenn entweder S ein Subtyp von T oder T ist ein Subtyp von S

Es funktioniert genau auf diese Weise in jedem Beispiel:

const foo3 = { n: '' } as Foo; // KO: "Property 's' is missing..." 

hier zwei Typen: {n?: number, s: string} und {n: string} sind auf Kompatibilität geprüft - ob einer von ihnen kann in einer anderen umgewandelt werden. Es kann nicht so oder so gemacht werden: {n: string} fehlt nicht-optional s und n hat den falschen Typ (muss number | undefined sein); Auf andere Weise hat {n?: number, s: string} einen falschen Typ für n (muss string sein).

Die vollständige Fehlermeldung ist

Type '{ n: string; }' cannot be converted to type 'Foo'. 
    Property 's' is missing in type '{ n: string; }'. 

Wenn Strukturtyp Unverträglichkeit berichtet, der Compiler nur eine inkompatible Eigenschaft wählt in der Fehlermeldung zeigen - dass einer der drei oben genannten Unvereinbarkeiten sein könnte.


const foo4 = { n: '' as any } as Foo; // ok 

Works weil {n?: number, s: string} mit {n: any} kompatibel ist: die erste mit dem zweiten zugeordnet werden - any mit allem kompatibel ist und s wird nur (im Grunde ignoriert, ein Wert ist kompatibel mit dem Typ, wenn es hat alle nicht-optionale Eigenschaften kompatibel mit deklarierten Typ)


const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..." 

{n: number, x: number} ist nicht zuordenbar {n?: number, s: string} - s fehlt, wie Compiler sagt:

Type '{ n: number; x: number; }' cannot be converted to type 'Foo'. 
    Property 's' is missing in type '{ n: number; x: number; }'. 

const foo6 = { s: '', x: 2 } as Foo; // ok 

Works weil {s: string, x: number} zu {n?: number, s: string} zuordenbar ist: s ist OK, fehlt n OK ist, weil es als optional deklariert wird, Extra x wird ignoriert


const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible." 

Typ s ist unvereinbar:

Type '{ s: number; x: number; }' cannot be converted to type 'Foo'. 
    Types of property 's' are incompatible. 
    Type 'number' is not comparable to type 'string'. 
Verwandte Themen