TypeScript 实现函数重载的方式

作者:青柠时间:2026-10-31 13:33:08浏览:228

本文介绍 TypeScript 中函数重载的实现机制。由于 JS 不支持重载,TS 仅做类型提示,需手动处理逻辑。文章展示了通过 Map 映射表手动实现重载的方法,并进一步封装为抽象类,利用构造函数限制实例化,实现继承类中多个函数的自动重载映射,提升代码可读性与维护性。

函数重载

JavaScript 语言本身并未提供函数重载机制。

TypeScript 所提供的函数重载功能,主要作用在于提供类型提示,具体的逻辑实现仍需开发者手动编写。

所谓函数重载,简单来说,就是针对同一个函数提供多种不同的实现方式。系统会根据传入参数的类型或长度,自动决定调用哪一个具体的实现版本。

最终效果方面,TypeScript 的类型校验机制也会随之发生变化,确保调用时的参数匹配。

函数重载

函数重载

函数重载

函数重载

代码实现

创建函数重载函数

根据传入参数的类型,调用对应的实现逻辑;若未找到匹配的实现,则抛出错误。

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")

为了封装一层,因为上述直接使用的写法缺乏代码提示,而开发者离不开代码提示的辅助。

创建抽象类。

在 JavaScript 中创建抽象类的方法,是在构造函数中执行 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 函数重载的资料请关注本站其它相关文章!

作者最新文章
相关文章
更多