2017-09-13 3 views
0

Ich habe eine Funktion, die einige Überladungen hat.TypeScript Überladungen und optionale Argumente

function foo(x: number, y: void): void; 
function foo(x: number, y: number | string): number; 
function foo(x: number, y: any) { 
    if (typeof y === "undefined") { 
     return; 
    } 
    return typeof y === "string" 
     ? x/parseFloat(y) 
     : x/y; 
} 

Statt für y das optionale Argument zu verwenden, verwende ich void speziell den Rückgabewert angeben. Die beabsichtigten Anwendungsfälle enthalten einen, wo es mit undefined als zweites Argument aufgerufen wird.

function bar(x: number, y?: number | string) { 
    const f = foo(x, y); 
    // Some other stuff 
} 

Dies führt zu dem folgenden Typ Fehler:

In einer anderen Funktion, ich mag es so nennen

Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'. 
    Type 'undefined' is not assignable to type 'string | number'. 

war mein Verständnis, dass foo als zweites Argument nehmen würde ein string | number | void, und wenn bar es aufruft, würde es entweder string, number oder void übergeben werden, und TypeScript wäre über die foo klar ' s Rückgabewert.

Was ist der richtige Weg, um den beabsichtigten Effekt zu erzielen?

Antwort

1

Es gibt keine Möglichkeit für den Compiler zu wissen, ob y innerhalb bar vom Typ seiner number | string oder undefined da beide möglich sind. Wenn der Compiler das nicht herausfinden kann, gibt es keine Möglichkeit, die richtige Überladung auszuwählen. Sie müssen mehr Hilfe für den Compiler bieten:

behaupten, dass y nie undefined sein kann:

function bar(x: number, y?: number | string) { 

    // Picks `function foo(x: number, y: number | string): number;` overload 
    const f = foo(x, y!); // Use the non-null assertion operator here. 
    // Some other stuff 
} 

Oder verwenden type guards:

function bar(x: number, y?: number | string) { 

    if (y === undefined) { 
     // Picks `function foo(x: number, y: void): void;` overload 
     foo(x, y); 
    } 
    else { 
     // Picks `function foo(x: number, y: number | string): number;` overload 
     const a = foo(x, y); 
    } 
    // Some other stuff 
} 
Verwandte Themen