函数重载
JavaScript并没有提供函数重载
TypeScript提供的函数重载,仅仅用作提示效果,实现还需手动
函数重载简单点说就是,同一个函数的不同实现方式,根据传入的参数的类型或者长度,决定最终调用哪一个实现
最终效果,TypeScript的类型校验也会变化
code
创建函数重载函数
根据参数的类型,调用不同的实现,如果没有对应的实现,则报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | export function createOverload () { const map: Map = new Map(); const overload = ( ...args: any[] ) => { const key = args.map( it => typeof it ).join( " " ); const fn = map.get( key ); if ( !fn ) throw new Error( "No overload function matched" ); return fn( args ); }; overload.addImpl = function ( args: Array, fn: Function ) { if ( typeof fn !== "function" ) throw new Error( "last argument must be a function" ); const key = args.join( " " ); map.set( key, fn ); }; return overload; } |
使用
1 2 3 4 5 6 7 8 9 10 11 | const overload = createOverload() overload.addImpl([ "string" , "number" ],()=>{ console.log( "string number" ) }) overload.addImpl([ "number" , "string" ],()=>{ console.log( "number string" ) }) overload( "yang jun" ,18) // console.log("string number") overload(18, "yang jun" ) // console.log("number string") |
封装一层,因为上述使用没有代码提示,离了代码提示活不下去了
创建抽象类。
在JS中创建抽象类方法,在construct中执行 if( new.target === Overload ) throw new Error("不允许直接new")
在下述实现中,转为 es6 类实现,新增了重载函数的映射表,用于继承类的多个函数的重载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | export abstract class Overload { private overloads = new Map(); protected addImpl ( name: string, args: Array, fn: Function ) { let overload = null ; if ( this .overloads.has( name ) ) { overload = this .overloads.get( name ); } else { overload = createOverload(); this .overloads.set( name, overload ); } overload.addImpl( args, fn ); }; protected getOverload ( name: string ): Function | undefined { if ( this .overloads.has( name ) ) return this .overloads.get( name ); throw new Error( "No overload matched" ); } } |
使用
非常舒服,再也不用自己在函数中写一串的 if 了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import { Overload } from "./utils" ; class Test extends Overload { constructor () { super (); this .addImpl( "getInfo" , [ "boolean" , "number" , "string" ], () => { console.log( "boolean" , "number" , "string" ); } ); this .addImpl( "getInfo" , [ "number" , "string" , "boolean" ], () => { console.log( "number" , "string" , "boolean" ); } ); this .addImpl( "getInfo" , [ "string" , "number" , "boolean" ], () => { console.log( "string" , "number" , "boolean" ); } ); } getInfo ( age: number, name: string, isHandsome: boolean ): Object; getInfo ( isHandsome: boolean, age: number, name: string ): Object; getInfo ( name: string, age: number, isHandsome: boolean ): Object; getInfo (): Object { const overload = this .getOverload( "getInfo" ); return overload( ...arguments ); } getName ( name: string ) { } } const test = new Test(); test.getInfo( 18, "yang jun" , true ); // console.log( "number", "string", "boolean" ); test.getInfo( "yang jun" , 18, true ); // console.log( "string", "number", "boolean" ); test.getInfo( true , 18, "yang jun" ); // console.log( "boolean", "number", "string" ); |
以上就是Typescript 实现函数重载的方式的详细内容,更多关于Typescript函数重载的资料请关注IT俱乐部其它相关文章!