【问题标题】:TypeScript: function expression overloadsTypeScript:函数表达式重载
【发布时间】:2018-07-18 08:31:34
【问题描述】:

我有这个 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;

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

【问题讨论】:

标签: function typescript overloading


【解决方案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;
};

【讨论】:

  • 您好,谢谢!我知道使用类型转换的选项。但是,我想知道为什么函数声明和表达式之间的行为不一样,以及函数表达式的等效代码是什么(不求助于类型转换)。有一个避免类型转换的解决方案:使函数表达式签名使用泛型。但是,这并不等同于使用联合的函数声明。
  • @OliverJosephAsh 在这种情况下使用泛型将是相似的,但实际上并不等同。函数表达式无法指定多个重载。我的猜测是因为函数表达式可以出现在任何地方,团队可能认为以这种方式更改语言太危险(未来 JS 语言更改的可能性太大而无法以某种方式破坏它)但我只是推测。
猜你喜欢
  • 2012-10-24
  • 1970-01-01
  • 2012-09-30
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
相关资源
最近更新 更多