2016-12-07 5 views
1
in der Schnittstelle entlang

ich mit dem folgenden Typoskript bin zu kämpfen Problem kompilieren:Stringliteral und optionale Parameter nicht bekommen

const Names = { 
    francesco: 'francesco' 
} 

export interface A { 
    name: 'francesco'; 
    age?: number; 
} 

const e: A = { name: Names.francesco, age: 26 }; 

Der Typoskript Compiler gibt die folgenden:

Type '{ name: string; age: number; }' cannot be converted to type 'A'. 
    Types of property 'name' are incompatible. 
    Type 'string' is not comparable to type '"francesco"'. 
(property) francesco: string 

Aber ich fanden zwei Möglichkeiten, den Compiler Stop beschwerte sich über die Stringliteral zu machen:

Methode 1

Den optionalen Parameter "age" der Schnittstelle A obligatorisch machen.

Methode 2

diese Zeile ersetzen

const e: A = { name: Names.francesco, age: 26 }; 

mit

const e: A = { name: 'francesco', age: 26 }; 

Hat warum geschieht dies eine Erklärung jemand haben?

+0

Warum ist Ihr Schnittstelle Namen deklariert eine Zeichenfolge zu sein Literaler Typ? 'name: string' in der Schnittstelle scheint mir korrekt zu sein. – silentsod

+0

@silentsod Das Beispiel ist eine Vereinfachung eines größeren Szenarios, in dem es sinnvoll ist, das Feld "name" als String-Literal anzugeben. Zum Beispiel möchte ich mehrere Schnittstellen dieser Art mit unterschiedlichen String-Literalen und verschiedenen optionalen Parametern haben: Schnittstelle B { Name: "jon"; Alter ?: Nummer; verpflichtend: any; } – francesco

+0

Sie geben die Schnittstelle an, 'name' mit einem Typ' 'francesco' 'zu haben. Die Schnittstelle sollte Unterstützung für den allgemeinen Fall bieten (Namen sind Zeichenfolgen) und die Implementierungen der Schnittstelle werden spezifischer (z Implementierung, wo jeder Name ist "Francesco". Was Sie haben, ist im Wesentlichen rückwärts von, wie Schnittstellen tatsächlich verwendet werden. – silentsod

Antwort

1

Es ist, weil Names.francesco wie string eingegeben wird und string nicht dem Typ 'francesco' zuweisbar ist. Der Grund dafür ist, dass eine string nicht garantiert ist "Francesco".

Sie wollen wahrscheinlich Ihre Schnittstelle ändern, als Zeichenfolge eingeben name:

export interface A { 
    name: string; 
    age?: number; 
} 

Oder Names.francesco als 'francesco' eingegeben werden ändern:

const Names = { 
    francesco: 'francesco' as 'francesco' 
}; 
+0

Vielen Dank.Dies erklärt, warum der Compiler mit Methode 2 funktioniert. Aber Warum funktioniert Methode 1? – francesco

+0

@francesco sollte es nicht mit Methode 1 funktionieren. [Ich kann das nicht reproduzieren] (https://www.typescriptlang.org/ play/# src = const% 20Namen% 20% 3D% 20% 7B% 0A% 20% 20% 20% 20Francesco% 3A% 20'Francesco '% 0A% 7D% 0A% 0Axport% 20Interface% 20A% 20% 7B% 0A% 20% 20% 20% 20Name% 3A% 20'Francesco '% 3B% 0A% 20% 20% 20% 20%% 3A% 20Anzahl% 3B% 0A% 7D% 0A% 0Aconst% 20e% 3A% 20A% 20 % 3D% 20% 7B% 20Name% 3A% 20Namen.Francesco% 2C% 20%% 3A% 2026% 20% 7D% 3B). –

+0

Korrektur: Methode 1 funktioniert, wenn ich das Objekt auf A [link] (https://www.typescriptlang.org/play/#src=const%20Names%20%3D%20%7B%0D%0A%09francesco% 3A% 20'Francesco '% 0D% 0A% 7D% 0D% 0A% 0D% 0AExport% 20Schnittstelle% 20A% 20% 7B% 0D% 0A% 09Name% 3A% 20'Francesco'% 3B% 0D% 0A% 09age% 3A% 20Anzahl% 3B% 0D% 0A% 7D% 0D% 0A% 0D% 0A% 0D% 0Aconst% 20e% 3A% 20A% 20% 3D% 20% 7B% 20Name% 3A% 20Names.francesco% 2C% 20age% 3A% 2026% 20% 7D% 20as% 20A% 3B) – francesco