[英]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.