Surcharge de la fonction TypeScript
La Section 6.3 de la spécification du langage TypeScript parle de la surcharge de fonction et donne des exemples concrets sur la façon de l'implémenter. Cependant, si j'essaie quelque chose comme ceci:
export class LayerFactory {
constructor (public styleFactory: Symbology.StyleFactory) { }
createFeatureLayer (userContext : Model.UserContext, mapWrapperObj : MapWrapperBase) : any {
throw "not implemented";
}
createFeatureLayer(layerName : string, style : any) : any {
throw "not implemented";
}
}
J'obtiens une erreur de compilateur indiquant l'identifiant en double même si les paramètres de fonction sont de types différents. Même si j'ajoute un paramètre supplémentaire à la deuxième fonction createFeatureLayer, j'obtiens toujours une erreur de compilateur. Des idées, s'il vous plaît.
5 réponses
Cela peut être dû au fait que, lorsque les deux fonctions sont compilées en JavaScript, leur signature est totalement identique. Comme JavaScript N'a pas de types, nous finissons par créer deux fonctions prenant le même nombre d'arguments. Ainsi, TypeScript nous empêche de créer de telles fonctions.
TypeScript prend en charge la surcharge en fonction du nombre de paramètres, mais les étapes à suivre sont un peu différentes si l'on compare aux langues OO. En réponse à une autre question SO, quelqu'un l'a expliqué avec une belle exemple: surcharge de méthode?.
Fondamentalement, ce que nous faisons est de créer une seule fonction et un certain nombre de déclarations afin que TypeScript ne donne pas d'erreurs de compilation. Lorsque ce code est compilé en JavaScript, la fonction concrète seule sera visible. Comme une fonction JavaScript peut être appelée en passant plusieurs arguments, cela fonctionne juste.
Lorsque vous surchargez en TypeScript, vous n'avez qu'une seule implémentation avec plusieurs signatures.
class Foo {
myMethod(a: string);
myMethod(a: number);
myMethod(a: number, b: string);
myMethod(a: any, b?: string) {
alert(a.toString());
}
}
Seules les trois surcharges sont reconnues par TypeScript comme des signatures possibles pour un appel de méthode, pas l'implémentation réelle.
Dans votre cas, j'utiliserais personnellement deux méthodes avec des noms différents car il n'y a pas assez de points communs dans les paramètres, ce qui rend probable que le corps de la méthode devra avoir beaucoup de "ifs" pour décider quoi faire.
Tapuscrit 1.4
À partir de TypeScript 1.4, vous pouvez généralement supprimer la nécessité d'une surcharge en utilisant un type d'union. L'exemple ci-dessus peut être mieux exprimé en utilisant:
myMethod(a: string | number, b?: string) {
alert(a.toString());
}
Le type de a
est "soit string
ou number
".
Vous pouvez déclarer une fonction surchargée en déclarant la fonction comme ayant un type qui a plusieurs signatures d'invocation:
interface IFoo
{
bar: {
(s: string): number;
(n: number): string;
}
}
Puis ce qui suit:
var foo1: IFoo = ...;
var n: number = foo1.bar('baz'); // OK
var s: string = foo1.bar(123); // OK
var a: number[] = foo1.bar([1,2,3]); // ERROR
La définition réelle de la fonction doit être singulière et effectuer la répartition appropriée en interne sur ses arguments.
Par exemple, en utilisant une classe (qui pourrait implémenter IFoo
, mais n'a pas à le faire):
class Foo
{
public bar(s: string): number;
public bar(n: number): string;
public bar(arg: any): any
{
if (typeof(arg) === 'number')
return arg.toString();
if (typeof(arg) === 'string')
return arg.length;
}
}
Ce qui est intéressant ici, c'est que la forme any
est caché par les remplacements plus spécifiquement typés.
var foo2: new Foo();
var n: number = foo2.bar('baz'); // OK
var s: string = foo2.bar(123); // OK
var a: number[] = foo2.bar([1,2,3]); // ERROR
Comme un heads up aux autres, j'ai oberserved qu'au moins comme manifesté par TypeScript compilé par WebPack pour Angular 2, vous obtenez tranquillement écrasé au lieu de méthodes surchargées.
myComponent {
method(): { console.info("no args"); },
method(arg): { console.info("with arg"); }
}
Appel:
myComponent.method()
Semble exécuter la méthode avec des arguments, ignorant silencieusement la version no-arg, avec output:
with arg
I getting function overload error on visual studio code.
**[ts] Duplicate function implementation.
function greet(): string (+1 overload)**
function greet():string{
return 'Hello';
}
let message=greet();
console.log(message);
function greet(message:string):string{
return message;
}
let newMessage=greet('Hello how are you');
console.log(newMessage);
Result : undefined (result of no arg greet method)
Hello how are you
Please explain why undefined.