Перегрузка функции TypeScript

раздел 6.3 спецификации языка TypeScript рассказывает о перегрузке функций и дает конкретные примеры того, как это реализовать. Однако, если я попробую что-то вроде этого:

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

}

Я получаю ошибку компилятора, указывающую на дубликат идентификатора, даже если параметры функции имеют разные типы. Даже если я добавлю дополнительный параметр ко второй функции createFeatureLayer, я все равно получу ошибку компилятора. Идеи, пожалуйста.

5 ответов


Это может быть потому, что, когда обе функции компилируются в JavaScript, их подписи абсолютно идентичны. Поскольку JavaScript не имеет типов, мы в конечном итоге создаем две функции с одинаковым количеством аргументов. Таким образом, TypeScript ограничивает нас в создании таких функций.

TypeScript поддерживает перегрузку на основе количества параметров, но шаги, которые следует выполнить, немного отличаются, если мы сравниваем с языками OO. В ответ на другой вопрос SO, кто-то объяснил это с помощью хороший пример: перегрузка методов?.

в принципе, мы создаем только одну функцию и несколько объявлений, чтобы TypeScript не давал ошибок компиляции. Когда этот код компилируется в JavaScript, будет видна только конкретная функция. Поскольку функцию JavaScript можно вызвать, передав несколько аргументов, она просто работает.


при перегрузке в TypeScript, у вас есть только одна реализация с несколькими подписями.

class Foo {
    myMethod(a: string);
    myMethod(a: number);
    myMethod(a: number, b: string);
    myMethod(a: any, b?: string) {
        alert(a.toString());
    }
}

только три перегрузки распознаются TypeScript как возможные подписи для вызова метода, а не фактическая реализация.

в вашем случае я бы лично использовал два метода с разными именами, поскольку в параметрах недостаточно общности, что делает вероятным, что тело метода должно будет иметь много "Если", чтобы решить, что делать.

машинопись 1.4

начиная с TypeScript 1.4, вы обычно можете удалить необходимость перегрузки с помощью типа объединения. Приведенный выше пример может быть лучше выражен с помощью:

myMethod(a: string | number, b?: string) {
    alert(a.toString());
}

тип a это "либо string или number".


вы можете объявить перегруженная функция, объявив функцию как имеющую тип, который имеет несколько сигнатур вызова:

interface IFoo
{
    bar: {
        (s: string): number;
        (n: number): string;
    }
}

Затем следующее:

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

фактический определение функции должны быть сингулярными и выполнять соответствующую диспетчеризацию внутри своих аргументов.

например, используя класс (который может реализовать IFoo, но не обязательно):

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

что интересно вот что то any формы скрытый более конкретно типизированными переопределениями.

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

в качестве головы до других, я обер-сервировал, что, по крайней мере, как проявляется TypeScript, скомпилированный WebPack для Angular 2, вы спокойно перезаписываетесь вместо перегруженных методов.

myComponent {
  method(): { console.info("no args"); },
  method(arg): { console.info("with arg"); }
}

тел.:

myComponent.method()

кажется, выполняет метод с аргументами, молча игнорируя версию no-arg, с выходом:

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.