Машинопись перегрузка функций


В разделе 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 164

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 как возможные сигнатуры для вызова метода, а не фактическая реализация.

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

TypeScript 1.4

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

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.