2012-10-06 5 views
17

Ich scheine nicht in der Lage sein, der folgende Code zu verstehen, warum Fehler nicht erhöhen:TypeScript: void Rückgabetyp in einen beliebigen Typ konvertiert?

var rg: {(): void;}[] = []; 
rg.push(function():string {return "";}) 

ich klar zum Ausdruck, dass der Typ eine Reihe von Funktionen sein sollte, die void zurückkehren, aber schiebe ich eine Funktion gibt, die zurückgibt a string und noch der Compiler nicht beklagen. Wenn ich die Definition von rg zu

var rg: {():number;}[] = []; 

Der Compiler ändern beginnt sich zu beschweren.

Ist das ein Fehler oder ist es wie der void Rückgabetyp funktionieren soll (d. H. Alles geht, wenn void verwendet wird, im Grunde dasselbe als Rückgabetyp any)?

+0

Ich habe [ein Problem eingereicht] (http://typescript.codeplex.com/workitem/139). –

Antwort

17

Dies ist mit Absicht (ich werde erklären, warum es in Kürze ein gutes Design ist). Die Spezifikation sagt (in Abschnitt 3.6.3, verkürzte für Klarheit):

A type S is assignable to a type T, and T is assignable from S, if one of the following is true...

  • S and T are object types and, for each member M in T, one of the following is true:

    • M is a call, construct or index signature and S contains a call, construct or index signature N where

      • the result type of M is Void, or the result type of N is assignable to that of M.

In diesem Fall wir testen, ob () => string-() => void zuordenbar ist. Also entweder string muss void zugewiesen werden (ist es nicht), oder void muss void sein (es ist).


In der Tat hier die Regel ist Sie erlaubt den Rückgabewert, die mit, wie zum Beispiel im Einklang wegzuwerfen C++ behandelt void in Vorlagenauflösung.

function decrementWidgetHeight(w: Widget): number { 
    // ... returns the new height of the widget 
} 

function applyToManyWidgets(w: Widget[], change: (x: Widget) => void): void { 
    // for each widget in the array, apply 'change' to it 
} 

// Later... 
applyToManyWidgets(widgetsToShorten, decrementWidgetHeight); // Should be allowed? 

Wenn wir die Art der change beschränken (widget) => void zu sein, wir machen es so, dass Sie decrementWidgetHeight als zweites Argument übergeben kann, auch wenn es einen Rückgabewert hat, aber noch dafür sorgen, dass, wenn wir Schreiben Sie den Körper von applyToManyWidgets, wir verwenden nicht versehentlich den Rückgabewert von change irgendwo.

Beachten Sie, dass void als any noch anders ist, weil diese unerlaubt ist:

function f() { } 
var x = f(); // Disallowed, f() is of type 'void' 
+0

+1 - Sie können dies testen mit: 'var rg: {(): void;} [] = []; rg.push (function(): string {return "";}) var x = rg [0](); 'im TypeScript-Bereich, um das Verhalten in Aktion zu sehen. Ändern Sie 'void' in' string' und es wird der Rückgabewert verwendet. – Fenton

+0

Okay, es macht Sinn, ist aber ein wenig kontra intuitiv, d. H. Es erlaubt, eine Funktion hinzuzufügen, die nicht mit dem Typ übereinstimmt, auch wenn sie in der Definition ungültig ist. –

+1

Die Spezifikation sagt auch, dass "void nur zu den Typen Undefined, Null und Any gehört", also bin ich mir nicht sicher, ob die Spezifikation konsistent ist. Definitiv unerwartet. – Roly

0

Das sieht wie ein Fehler aus. Sie sollten eine new work item für das Problem öffnen

+0

[Habe das getan] (https://typescript.codeplex.com/workitem/1734), aber angesichts des obigen Kommentars denke ich, dass das beabsichtigt ist. Generatoren, die bisher in TS noch nicht viel genutzt haben ... – Roly

Verwandte Themen