2017-09-13 2 views
0

J'ai une fonction qui a quelques surcharges.Surcharge de typeScript et arguments facultatifs

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; 
} 

Au lieu d'utiliser l'argument optionnel pour y, j'utilise spécifiquement void pour spécifier la valeur de retour. Les cas d'utilisation prévus incluent un cas où il est appelé avec undefined comme deuxième argument.

Dans une autre fonction, je vais l'appeler comme ceci:

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

Cela provoque l'erreur de type:

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

Je crois comprendre que foo prendrait comme second argument un string | number | void, et que lorsque bar invoque, il serait passé soit string, number, ou void, et TypeScript serait clair sur le foo ' s valeur de retour.

Quelle est la bonne façon d'atteindre l'effet recherché?

Répondre

1

Il n'y a aucun moyen pour le compilateur de savoir si l'intérieur ybar sera de type number | string ou undefined puisque les deux sont possibles. Si le compilateur n'est pas capable de comprendre cela, il ne peut pas choisir la surcharge correcte. Vous devez fournir plus d'aide au compilateur:

Assertion que y ne peut jamais être undefined:

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 
} 

Ou utilisez 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 
}