簡體   English   中英

在打字稿中實現函數重載

[英]Implement function overloading in typescript

我知道打字稿和JavaScript不支持函數重載。

而且我正在研究一種繞過這種方法重載的繞線方法。

我的情況如下。

第一:

最后一個和第一個參數是固定的。

public A(arg1:number, arg2:number, argLast:any){

}

public A(arg1:number, arg2:number, arg3:Array<any>, argLast:any){

}

第二:

在此處輸入圖片說明

有一個用於指示該功能是否過載的指示器。

當然,就像上面的示例一樣,這是可能的,但是我必須通過新的界面來創建它,因此它不適合我的情況。

我嘗試了各種函數重載方法。

我還通過john resig博客實現了它。

https://johnresig.com/blog/javascript-method-overloading/

下面的代碼是我通過上述博客撰寫的示例。

function addMethod (object, name, fn) {
  var old = object[ name ]
  object[ name ] = function () {
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments)
    } else if (typeof old === 'function') {
      return old.apply(this, arguments)
    }
  }
}

export class Users{
  find(...arg: any[]){
    Users.prototype['findOVF'](arg)
  }
}
addMethod(Users.prototype, 'findOVF', function () {
  console.log('ARG 0')
})
addMethod(Users.prototype, 'findOVF', function (name:string, age:number) {
  console.log('ARG 2')
})
addMethod(Users.prototype, 'findOVF', function (first_name:string, last_name:string,age:number) {
  console.log('ARG 3')
})

var users = new Users()
users.find() 
users.find('John',19) 
users.find('John', 'Resig', 19) 

使用此方法時,我使用參數(... arg)調用該函數。

我試圖實現下面博客的所有方法。

https://blog.mariusschulz.com/2016/08/18/function-overloads-in-typescript

public A(arg1:number, arg2:number, argLast:any){

}

public A(arg1:number, arg2:number, arg3:Array<any>|null, argLast:any){

}

如果以這種方式實現函數重載,則每次調用A函數時都會出錯。 它並不是真正的函數重載。

但是我沒有找到同時實現這兩個元素的方法。

我想知道這對於打字稿語法是不可能的,還是有其他可能性。

感謝您看到我的英語尷尬。

您可以在Typescript中創建重載,但所有重載都具有單個實現,您可以在它們之間進行區分。 如果僅通過參數數量來區分所有方法,則最簡單的解決方案是:

class User { }
export class Users {
    find(): User;
    find(name: string, age: number): User;
    find(first_name: string, last_name: string, age: number): User
    find(...args: [any?, any?, any?]): User {
        if (args.length == 0) {
            return null as any;
        } else if (args.length == 1) {
            let [name, age, _]: [string?, number?, any?] = args;
            console.log(`${name}, ${age}`);
            return null as any;
        } else if (args.length == 2){
            let [first_name, last_name, age]: [string?, string?, number?] = args;
            console.log(`${first_name}, ${last_name}, ${age}`);
            return null as any;
        } else {
            throw "Not implemented";
        }
    }
}

游樂場鏈接

上面的解決方案保留了呼叫站點類型的安全性,您的解決方案則沒有,因為在示例中find的參數是any[]

您可以通過定義一個函數來使用更自動化的方法,該函數將通過函數數組創建一個重載函數,但是這種額外的復雜性值得您作為評判。

type UnionToIntersection<U> =
    (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

function overloads<TThis>(){
    return function<T extends Array<(this: TThis, ...args: any[]) => any>>(...fns: T): UnionToIntersection<T[number]> {
        return function (this: TThis, ...args: any[]) {
            for (var fn of fns) {
                if (fn.length === args.length) {
                    return fn.apply(this, args);
                }
            }
            throw "Not implemented";
        } as any
    }
}

class User { }
export class Users {
    member: string = "M"
    find = overloads<Users>()(
        function () {
            console.log('ARG 0');
            this.member // this is Users 
        },
        function (name: string, age: number) {
            console.log('ARG 2')
        },
        function (first_name: string, last_name: string, age: number) {
            console.log('ARG 3')
        }
    );
}

var users = new Users()
users.find('John', 19)
users.find('John', 'Resig', 19) 

游樂場鏈接

或將功能分配給原型而不是實例的版本:

export class Users {
    member: string = "M"
}

let find = overloads<Users>()(
    function () {
        console.log('ARG 0');
        this.member // this is Users 
    },
    function (name: string, age: number) {
        console.log('ARG 2')
    },
    function (first_name: string, last_name: string, age: number) {
        console.log('ARG 3')
    }
);
export interface Users {
    find: typeof find;
}
Users.prototype.find = find;

游樂場鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM