2017-06-07 5 views
3

Ich möchte den qualifizierten Typ für die Funktionen, die als Parameter angegeben werden. Dieser Typ erwartet entweder eine Funktion ohne Parameter, die eine void-Funktion (Action) zurückgibt, die Parameter enthält, oder die void-Funktion, die sie selbst zurückgibt.Typoskript: Implizite No-Parameter-Funktion Typ

Hier ist der Code, den ich verwenden möchten:

interface JsonArray extends Array<string | number | boolean | Date | Json | JsonArray> { } 

interface Json { 
    [x: string]: string | number | boolean | Date | Json | JsonArray; 
} 

type Action = (arg1: string, arg2: Json | JsonArray) => void; 
type ReturningAction =() => Action; 

function required(arg1: string, ...validationFunctions: Array<ReturningAction | Action>) { 
    console.log("Test"); 
} 

function oneOf(arg1: string): (arg1: string, arg2: Json | JsonArray) => void { 
    return (arg1: string, arg2: Json | JsonArray) => { 
     console.log("Testing"); 
    } 
} 

function notEmpty(): (arg1: string, arg2: Json | JsonArray) => void { 
    return (arg1: string, arg2: Json | JsonArray) => { 
     console.log("Empty"); 
    } 
} 

required("field", oneOf); // Shouldn't be accepted 
required("field", oneOf("test")) // Should be accepted 
required("field", notEmpty); // Should be accepted 

aber es scheint, Typoskript ignoriert zusätzliche Parameter innerhalb der Funktionsdefinition als erwartet. Kann das gelöst werden?

Auch wenn ich wie folgt vorgehen:

function required(arg1: string, ...validationFunctions: Array<(arg1: string, arg2: Json | JsonArray) => void>) { 
    console.log("Test"); 
} 

required("field", oneOf); // Shouldn't be accepted 
required("field", oneOf("test")) // Should be accepted 
required("field", notEmpty); // Shouldn't be accepted 
required("field", notEmpty()); // Should be accepted 

Alle aus irgendeinem Grunde akzeptiert, jedoch nur die aufgerufenen Funktionen anwenden.

Antwort

1

Wie ich glaube, Sie bemerkt, Typoskript allows Sie eine Funktion von weniger Parameter zu übergeben (zB oneOf() nimmt einen Parameter), um etwas, das eine Funktion von mehreren Parametern (in diesem Fall erwartet, sollte validationFunctions[0] zwei Parameter übernehmen, ist es unter der Annahme, ein Action). Das liegt daran, dass eine Funktion immer frei ist, zusätzliche übergebene Parameter zu ignorieren und einen Fehler zu verursachen, der an anderer Stelle zu ärgerlichen Fehlern führen würde (wie der verlinkte Abschnitt der TypeScript FAQ erklärt).

BEARBEITEN: Im Folgenden wird vorausgesetzt, dass Sie die Compileroption strictNullChecks verwenden.

Eine Abhilfe ist Ihre oneOf und notEmpty Funktionen zu erklären, so dass sie als normal arbeiten, aber nicht als Action Werte interpretiert werden:

function oneOf(arg1: string, nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...} 

function notEmpty(nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...} 

Beachten Sie die Zugabe des nope Parameters in jedem Fall. Jetzt sollten Sie Fehler erhalten, wo Sie sie erwarten. Da nope ein optionaler Parameter ist, können Sie es weglassen, und da es vom Typ never ist, müssen Sie ziemlich haben lassen Sie es heraus. Es ändert also nicht wirklich die Art, wie die Funktionen verwendet werden können.


Es gibt auch andere Korrekturen, aber sie sind schweres Gewicht ... Sie zum Beispiel Action und ReturningAction eines Nicht-Funktionstyp, den die Funktion enthält, die Sie anrufen machen.

Hoffe, dass hilft.

+0

Zunächst einmal, vielen Dank für Ihre Antwort! Es hilft jedoch auch nicht weiter, weil TypeScript sich nicht zu beschweren scheint, wenn ein Parameter eine Funktion mit Parametern erwartet, während Sie diese Funktion mit einer Funktion als Parameter aufrufen, der nur einen Parameter hat, ein optionales None vom Typ nie . Mache ich etwas falsch oder habe ich Recht? –

+0

Haha, ich kann das nicht ganz verstehen; Könnten Sie der Frage, die das Problem veranschaulicht, einen Code hinzufügen? – jcalz

+1

Angenommen, Ihre [neue Frage] (https://stackoverflow.com/questions/45896645) ist darüber, siehe meine Bearbeitung: Aktivieren Sie 'strictNullChecks'. – jcalz