打字稿重载箭头函数

Posted

技术标签:

【中文标题】打字稿重载箭头函数【英文标题】:Typescript overload arrow functions 【发布时间】:2017-01-04 09:13:59 【问题描述】:

所以我们可以这样做:

export function myMethod (param: number) :number
export function myMethod (param: string) :string

export function myMethod (param: string | number): string | number 
  if (typeof param === 'string') 
    return param.toUpperCase()
   else 
    return param + 1
  

可以用箭头函数声明和实现吗?

export var myMethodArror = (param: string): string
export var myMethodArror = (param: number): number

export var myMethodArror = (param: string | number): string | number => 
..

我知道不能复制变量声明,但我的问题是:是否可以使用箭头符号进行函数重载?

【问题讨论】:

当然不行。一个变量不能声明两次,一个变量声明不声明函数签名。这不是箭头函数的问题;如果您尝试执行export var myMethodArr = function(...),则同样适用。 但我的问题是可以使用箭头符号进行重载 谢谢,您不能发表评论,只能回答并从避风港获得奖金) 重复***.com/questions/20646171/… 【参考方案1】:

我猜它是在当时和现在之间添加的,因为您现在可以使用接口或类型来执行此操作(没关系,除了关键字之外的语法相同)。当然也可以作为出口。该函数必须命名(我认为所有重载函数都必须命名),因此如果您想将其用作回调,则必须先声明它。

type IOverload = 
    (param: number): number[];
    (param: object): object[];


const overloadedArrowFunc: IOverload = (param: any) => 
    return [param, param];


let val = overloadedArrowFunc(4);

我更喜欢这样,它减少了重复写作的需要。一遍又一遍地写名字很烦人。

另外,作为任何问题的序言,是的,我在实现中将参数声明为any。在当前状态下,这是允许编译的必要条件,是的,正如@ford04 指出的那样,您将失去函数内部的类型安全性。在函数及其返回方面,打字稿似乎仍然无法正确处理标记的联合。或者,您可以使用更严格的参数,但您必须将返回值强制转换为任何参数。

【讨论】:

这是一个实际的答案。我不同意重新写名字很烦人,但这解释了如何重载箭头函数的签名 这种方案的缺点是返回类型不能在函数体中进行类型检查。见here 这真的很棒。但是,当我测试我的类型检查时,将错误的第二个参数与我的第一个参数匹配时得到的错误(type overload = (first: type1a, second: type 1b): any, (first: type2a, second: type2b)The last overload gave the following error: Argument of type 'type1a' is not assignable to parameter of type 'type1b'. 这令人困惑,它应该类似于type1a can't go with type2b。有没有办法解决这个问题? <any> 只有不到一个半小时才认输对吧?同样的限制似乎仍然适用于我正在做的事情。 我喜欢这个...但是如何在 IOverload 中调用泛型?我想使用泛型来重载不同的类型。我正在尝试不同的东西,但无法正确使用语法。【参考方案2】:

此解决方案基于@Sam96,但保持箭头函数的代码完全键入。

type Create = 
  (): Vector<0>;
  <T>(x: T): Vector<T>;
  <T>(x: T, y: T): Vector<T>;
;

const create: Create = <T>(
  x?: T,
  y?: T
) => (
  x: x ?? 0,
  y: y ?? x ?? 0,
);

【讨论】:

这看起来很酷。您能否扩展此答案并解释当所有三个参数都具有需要您的 T 作为类型参数的不同泛型类型时它将如何工作?【参考方案3】:

您可以使用交集运算符&amp; 进行重载。

export let myMethodArror = ((param: string | number): string | number => 
...
) as ((param: string) => string) & ((param: number) => number)

【讨论】:

简洁明了。 如果您在项目中添加了 eslint,您将收到错误消息:'param' is defined but never used. eslint: no-unused-vars【参考方案4】:

重载签名的声明总是

function name(args...): result;

带有function 关键字和函数名。

你的语法

var myMethodArror = (param: string): string;

无效。它试图将看起来像箭头函数开头的东西分配给变量,但该函数没有主体。你会得到错误

'=>' 预期

如果你用不同的签名重复这个,那么你也会得到一个重复的属性错误,或者可能是错误

随后的变量声明必须具有相同的类型。

这并不特定于箭头函数。如果您尝试这样做,也会出现同样的问题

var myMethodArror = function(param: string): string;

这会产生

''预期

因为缺少函数体。

【讨论】:

以上是关于打字稿重载箭头函数的主要内容,如果未能解决你的问题,请参考以下文章

打字稿装饰器不能使用箭头函数

打字稿 - 在箭头(回调)函数中使用它 - 猫鼬

打字稿装饰器和箭头函数

在打字稿中应用箭头函数作为对象属性

带有箭头功能的打字稿装饰器

再次:打字稿函数重载