Typescript 实现函数重载的方式

函数重载简单点说就是,同一个函数的不同实现方式,根据传入的参数的类型或者长度,决定最终调用哪一个实现,本文给大家介绍了Typescript 实现函数重载的方式,需要的朋友可以参考下

函数重载

JavaScript并没有提供函数重载

TypeScript提供的函数重载,仅仅用作提示效果,实现还需手动

函数重载简单点说就是,同一个函数的不同实现方式,根据传入的参数的类型或者长度,决定最终调用哪一个实现

最终效果,TypeScript的类型校验也会变化

Typescript 实现函数重载的方式

Typescript 实现函数重载的方式

Typescript 实现函数重载的方式

Typescript 实现函数重载的方式

code

创建函数重载函数

根据参数的类型,调用不同的实现,如果没有对应的实现,则报错。

export function createOverload () {
    const map: Map<string, Function> = 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<"number" | "string" | "boolean" | "function" | "object" | "symbol" | "undefined" | "bigint">, 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;
}

使用

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 类实现,新增了重载函数的映射表,用于继承类的多个函数的重载。

export abstract class Overload {
    private overloads = new Map<string, Function>();
    protected addImpl ( name: string, args: Array<"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function">, 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 了

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函数重载的资料请关注站长课堂其它相关文章!

声明:本站所有信息内容均由用户自行发表,该内容观点仅代表用户本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。Email:tellusa@foxmail.com

给TA打赏
共{{data.count}}人
人已打赏
JS教程

vue中双token和无感刷新token的区别

2024-5-17 0:36:40

JS教程

JS中跳转传参的几种常用方法总结

2024-5-17 0:54:42

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
有新私信 私信列表
搜索