最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript 函數(shù)重載(Overloads)的實現(xiàn)示例

 更新時間:2026年05月13日 08:50:23   作者:燭銜溟  
本文主要介紹了TypeScript 函數(shù)重載(Overloads)的實現(xiàn)示例,它詳細描述了重載簽名、實現(xiàn)簽名的定義和使用規(guī)則,以及參數(shù)數(shù)量和類型不同的處理方式,感興趣的可以了解一下

一、為什么需要重載

1.1 問題場景

在 JavaScript 中,同一個函數(shù)可能根據(jù)傳入?yún)?shù)的類型或數(shù)量執(zhí)行不同邏輯并返回不同類型。TypeScript 的類型系統(tǒng)需要準確描述這種關(guān)系。

例如,一個函數(shù)接收字符串或字符串數(shù)組,分別返回翻轉(zhuǎn)后的字符串或翻轉(zhuǎn)后的數(shù)組:

function reverse(input: string | string[]): string | string[] {
    if (typeof input === "string") {
        return input.split("").reverse().join("");
    } else {
        return [...input].reverse();
    }
}

const revStr = reverse("hello");   // 類型推斷為 string | string[]
const revArr = reverse(["a","b"]); // 類型推斷為 string | string[]

問題:調(diào)用者知道傳入的是字符串,返回的也一定是字符串,但 TypeScript 推斷的是聯(lián)合類型,丟失了精確信息。

1.2 重載的解決方案

通過聲明多個重載簽名(overload signatures),告訴 TypeScript 不同參數(shù)組合對應(yīng)的返回值類型,再提供一個實現(xiàn)簽名(implementation signature)來實際執(zhí)行邏輯。

// 重載簽名
function reverse(input: string): string;
function reverse(input: string[]): string[];

// 實現(xiàn)簽名
function reverse(input: string | string[]): string | string[] {
    if (typeof input === "string") {
        return input.split("").reverse().join("");
    } else {
        return [...input].reverse();
    }
}

const revStr = reverse("hello");   // 類型為 string
const revArr = reverse(["a","b"]); // 類型為 string[]

二、重載語法與規(guī)則

2.1 重載簽名(Overload Signatures)

  • 寫在實現(xiàn)簽名之前,可以有多個。
  • 每個重載簽名包含參數(shù)列表和返回值類型,沒有函數(shù)體。
  • 參數(shù)類型必須具體,不能是聯(lián)合類型(實現(xiàn)簽名中的聯(lián)合類型是內(nèi)部使用的)。
function makeDate(timestamp: number): Date;           // 重載1
function makeDate(year: number, month: number, day: number): Date; // 重載2
function makeDate(...args: number[]): Date {           // 實現(xiàn)簽名
    if (args.length === 1) {
        return new Date(args[0]);
    } else if (args.length === 3) {
        return new Date(args[0], args[1], args[2]);
    }
    throw new Error("Invalid arguments");
}

2.2 實現(xiàn)簽名(Implementation Signature)

  • 必須兼容所有重載簽名(參數(shù)類型和返回值類型要能覆蓋)。
  • 實現(xiàn)簽名本身不能直接被調(diào)用,只有重載簽名暴露給外部。
  • 實現(xiàn)簽名中的參數(shù)類型通常使用聯(lián)合類型或可選參數(shù)來匹配重載。

2.3 重載解析規(guī)則

TypeScript 編譯器按順序匹配重載簽名,選擇第一個匹配的。因此,應(yīng)將更具體的重載放在前面,更寬泛的放在后面。

function fn(x: string): string;
function fn(x: number): number;
function fn(x: any): any { return x; }

fn("a");  // 匹配第一個,返回 string
fn(1);    // 匹配第二個,返回 number

如果將 number 重載放在 string 前面,對字符串調(diào)用仍會匹配第二個(因為 string 可賦值給 any,但 string 不能賦值給 number,所以不匹配),順序會影響能否找到正確重載。

2.4 參數(shù)數(shù)量不同的重載

重載可以基于參數(shù)個數(shù)區(qū)分,但需要實現(xiàn)簽名中處理可選參數(shù)或剩余參數(shù)。

function format(): string;
function format(prefix: string): string;
function format(prefix?: string): string {
    return prefix ? `${prefix}: data` : "data";
}

2.5 參數(shù)類型不同的重載

function getLength(value: string): number;
function getLength(value: any[]): number;
function getLength(value: any): number {
    return value.length;
}

getLength("hello"); // 5
getLength([1,2,3]); // 3

注意:如果兩個重載的參數(shù)類型有重疊(例如 stringany),需要確保順序或使用更精確的類型。

三、重載 vs 聯(lián)合類型

很多場景下可以用聯(lián)合類型參數(shù)配合類型守衛(wèi),而不必使用重載。但重載在返回值類型不同且與參數(shù)類型有精確映射關(guān)系時更有優(yōu)勢。

場景推薦方式原因
參數(shù)類型不同,返回值類型也不同(且一一對應(yīng))重載返回值類型精確
參數(shù)類型不同,返回值類型相同聯(lián)合類型參數(shù)代碼更簡潔
參數(shù)是聯(lián)合類型,返回值也是聯(lián)合類型但無映射關(guān)系聯(lián)合類型參數(shù) + 類型守衛(wèi)避免重載冗余

示例:返回值類型相同,不需要重載。

// 不需要重載
function log(value: string | number): void {
    console.log(value);
}

示例:返回值類型與參數(shù)類型一一對應(yīng),重載更好。

// 重載
function pick(value: string, start: number, length?: number): string;
function pick<T>(value: T[], start: number, length?: number): T[];
function pick(value: any, start: number, length?: number): any {
    // 實現(xiàn)
}

四、箭頭函數(shù)不支持重載

箭頭函數(shù)(函數(shù)表達式)不能像函數(shù)聲明那樣寫多個重載簽名。替代方案:

  • 使用函數(shù)聲明(function
  • 使用函數(shù)類型表達式 + 交叉類型模擬(不推薦,復(fù)雜且可讀性差)
// 錯誤:箭頭函數(shù)不能有重載
// const reverse = (input: string): string;
// const reverse = (input: string[]): string[]; // ?

// 正確:使用函數(shù)聲明
function reverse(input: string): string;
function reverse(input: string[]): string[];
function reverse(input: string | string[]): string | string[] {
    // 實現(xiàn)
}

如果需要保留箭頭函數(shù)的 this 綁定,可以內(nèi)部調(diào)用一個具名函數(shù)。

五、常見錯誤與注意事項

5.1 實現(xiàn)簽名可調(diào)用但不應(yīng)被外部調(diào)用

實現(xiàn)簽名的類型不會暴露給外部,但如果你直接調(diào)用實現(xiàn)簽名(例如傳入了聯(lián)合類型的參數(shù)),TypeScript 會報錯提示“此調(diào)用不匹配任何重載”。

function fn(x: string): string;
function fn(x: number): number;
function fn(x: any): any { return x; }

fn("a");   // OK
fn(1);     // OK
fn(true);  // ? 不匹配任何重載

5.2 重載簽名順序不當導(dǎo)致匹配錯誤

function fn(x: any): any;
function fn(x: string): string;
function fn(x: any): any { return x; }

fn("a"); // 匹配第一個(any),返回 any,丟失精確類型

應(yīng)將更具體的重載放在前面。

5.3 實現(xiàn)簽名不夠兼容

function fn(x: string): string;
function fn(x: number): number;
// 實現(xiàn)簽名參數(shù)類型不兼容(缺少 number)
function fn(x: string): string { // ? 實現(xiàn)簽名與重載不兼容
    return x;
}

實現(xiàn)簽名必須能處理所有重載簽名的參數(shù)。

5.4 不必要的重載

如果一個函數(shù)可以用可選參數(shù)或默認參數(shù)實現(xiàn),就不需要重載。

// 不必要的重載
function greet(): string;
function greet(name: string): string;
function greet(name?: string): string {
    return name ? `Hello, ${name}` : "Hello";
}

// 更好的寫法(默認參數(shù))
function greet(name: string = "Guest"): string {
    return `Hello, ${name}`;
}

5.5 重載與泛型

如果重載邏輯可以用泛型解決,優(yōu)先考慮泛型(后續(xù)文章會講)。泛型通常更簡潔。

// 重載方式
function first(arr: string[]): string;
function first<T>(arr: T[]): T;
function first(arr: any[]): any {
    return arr[0];
}

// 泛型方式(一個簽名就夠了)
function first<T>(arr: T[]): T {
    return arr[0];
}

六、綜合示例

// 定義一個坐標轉(zhuǎn)換函數(shù):支持不同輸入格式,返回統(tǒng)一的對象或數(shù)組
type Point2D = { x: number; y: number };

// 重載簽名
function toPoint(coords: [number, number]): Point2D;
function toPoint(x: number, y: number): Point2D;
function toPoint(coords: string): Point2D;
function toPoint(x: number | string | [number, number], y?: number): Point2D {
    if (typeof x === "number" && typeof y === "number") {
        return { x, y };
    }
    if (Array.isArray(x) && x.length === 2) {
        return { x: x[0], y: x[1] };
    }
    if (typeof x === "string") {
        const parts = x.split(",").map(Number);
        if (parts.length === 2 && !parts.some(isNaN)) {
            return { x: parts[0], y: parts[1] };
        }
    }
    throw new Error("Invalid input");
}

// 使用
const p1 = toPoint(10, 20);           // Point2D
const p2 = toPoint([30, 40]);          // Point2D
const p3 = toPoint("50,60");           // Point2D

// 另一個示例:創(chuàng)建日期,支持時間戳或年月日
function createDate(timestamp: number): Date;
function createDate(year: number, month: number, day: number): Date;
function createDate(arg1: number, arg2?: number, arg3?: number): Date {
    if (arg2 !== undefined && arg3 !== undefined) {
        return new Date(arg1, arg2, arg3);
    }
    return new Date(arg1);
}

const d1 = createDate(1672531200000);   // Date
const d2 = createDate(2025, 3, 20);     // Date

七、小結(jié)

概念說明
重載簽名多個,無函數(shù)體,定義外部可調(diào)用的參數(shù)與返回值組合
實現(xiàn)簽名一個,有函數(shù)體,必須兼容所有重載簽名
匹配順序按重載簽名順序匹配,具體重載在前,寬泛在后
參數(shù)數(shù)量不同實現(xiàn)簽名中用可選參數(shù)或剩余參數(shù)處理
參數(shù)類型不同實現(xiàn)簽名中用聯(lián)合類型處理
箭頭函數(shù)不支持重載,使用函數(shù)聲明替代
與泛型關(guān)系部分重載可被泛型簡化

到此這篇關(guān)于TypeScript 函數(shù)重載(Overloads)的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)TypeScript 函數(shù)重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

庆城县| 辽宁省| 项城市| 永春县| 中牟县| 辽宁省| 鹤壁市| 赤城县| 仪陇县| 隆回县| 林口县| 札达县| 靖安县| 阳城县| 个旧市| 通榆县| 板桥市| 曲阜市| 焦作市| 务川| 西和县| 新宁县| 太白县| 南康市| 聂拉木县| 区。| 时尚| 上虞市| 开平市| 道真| 安福县| 大新县| 阜康市| 彰化县| 商河县| 芷江| 哈巴河县| 托克逊县| 四平市| 友谊县| 旌德县|