网站搜索

TypeScript:函数表达式重载


我有这段 TypeScript 代码,它在一个函数声明上使用了重载。这段代码按预期工作。

function identity(x: string): string;
function identity(x: number): number;
function identity(x: string | number): string | number {
    return x;
}

const a = identity('foo') // string
const b = identity(1) // number
const c = identity({}) // type error (expected)

我正尝试用函数表达式来实现与此相同的效果,而不是函数声明,但我收到类型错误:

/* Type '(x: string | number) => string | number' is not assignable to type '{ (x: string): string; (x: number): number; }'.
    Type 'string | number' is not assignable to type 'string'.
        Type 'number' is not assignable to type 'string' */
const identity: {
    (x: string): string;
    (x: number): number;
} = (x: string | number): string | number => x;

我想知道如何使用函数表达式实现与函数重载相同的效果。

答案#1

你可以改为在函数实现上使用类型断言。在赋值中,兼容性的检查更严格,而使用断言时,则较弱。尽管如此,我们仍然可以获得相当程度的类型安全性(我不确定这是否等同于对重载到实现签名的检查,但看起来相当接近):

//OK
const identity = ((x: string | number): string | number => x) as {
    (x: string): string;
    (x: number): number;
};

// Error argument is incompatible
const identity2 = ((x: boolean): string | number => x) as {
    (x: string): string;
    (x: number): number;
};

// Error return type is incompatible 
const identity3 = ((x: string | number) => false) as {
    (x: string): string;
    (x: number): number;
};