我是否必须为TypeScript中的高阶函数类型指定参数名称?

谢谢

试图用TypeScript弄湿我的脚,我一直遇到麻烦今天一个旧功能浮出水面,并且作为练习,我很好奇是否可以将其转换为TypeScript。到目前为止,颈部已经完全疼痛。

declare type Ord = number | string;

// type signature for f sucks really bad
// (f: Ord => Ord => boolean) would be really nice, if possible
// but instead I have to give names (_) for the parameters? dumb
const arrayCompare = (f: (_: Ord) => (_: Ord) => boolean) => ([x,...xs]: Ord[]) => ([y,...ys]: Ord[]): boolean => {
  if (x === undefined && y === undefined)
    return true;
  else if (! f (x) (y))
    return false;
  else
    return arrayCompare (f) (xs) (ys);
}

// here the names of the parameters are actually used
const eq = (x: Ord) => (y: Ord) : boolean => x === y;

// well at least it works, I guess ...
console.log(arrayCompare (eq) ([1,2,3]) ([1,2,3]));             // true
console.log(arrayCompare (eq) (['a','b','c']) (['a','b','c'])); // true

因此,问题特别是关于(请参阅粗体

const arrayCompare = (f: (_: Ord) => (_: Ord) => boolean) => ...

f 期望该类型的高阶函数

Ord => Ord => boolean

但是如果我使用这种类型签名

// danger !! unnamed parameters
(f: (Ord) => (Ord) => boolean)

TypeScript将假定Ord参数名称,并且隐式类型为any

// what TypeScript thinks it means
(f: (Ord: any) => (Ord: any) => boolean)

当然,这不是我想要的,但这仍然是我得到的。为了得到我真正想要的,我必须为高阶函数指定参数的名称

// now it's correct
(f: (_: Ord) => (_: Ord) => boolean)

但这没什么意义。f在这种情况下,我只能访问,而f最终调用它时将无法访问将绑定的参数...

为什么必须在TypeScript中为高阶函数参数提供名称

这没有任何意义,并且会使函数签名冗长,丑陋,难于编写和难于阅读。


更新

“就参数名称而言,请考虑采用->(数字->数字->数字)->的回调的函数,因此,仅基于您选择的类型:加,减,乘,除,幂,比较其中只有一个是有意义的,现在,如果回调参数具有名称添加:(数字->数字->数字),选择将显而易见”Aleksey Bykov

我很高兴有机会对此进行回复。我可以用(number -> number -> number)签名命名更多的函数

  • firstsecondmodminmax
  • 按位函数&|xor<<,和>>
  • (x, y) => sqrt(sq(x) + sq(y))
  • (x, y) => x + x + y + y + superglobalwhocares
  • 以及您可以梦想的任何其他功能

为了清楚起见,我不建议不要给函数参数本身起一个名字。我建议不要给函数参数的参数起个名字...

// this
func = (f: (number => number => number)) => ...

// not this
func = (f: (foo: number) => (bar: number) => number)) => ...

为什么?很好,因为f不了解我将要提供的功能参数。

// for the record, i would never name parameters like this
// but for those that like to be descriptive, there's nothing wrong with these
const add = (addend: number) => (augend: number) => number ...
const sub = (minuend: number) => (subtrahend: number) => number ...
const divide = (dividend: number) => (divisor: number) => number ...
const mult = (multiplicand: number) => (multiplier: number) => number ...

// I could use any of these with my func
func (add ...)
func (sub ...)
func (divide ...)
func (mult ...)

如果尝试过,我将无法提供f参数的名称func因为谁知道我将使用哪个功能?所有这些都是适当的。

如果我尝试在其上加上名称,则会使用户无法想象功能的功能。

// maybe the user thinks only a division function can be specified (?)
func = (f: (dividend: number) => (divisor: number) => number) => ...

dividenddivisor不是一个不错的选择这里,是因为上面列出的任何功能将适合。最好的我能做到这一点

// provide generic name for f's parameters
func = (f: (x: number) => (y: number) => number) => ...

但是那有什么意义呢?它不像xy成为绑定标识符。并且xy没有提供任何附加说明-我想让明白我的意思:它们并不具有名称或说明。具有的我们可能会使用它的方式的知识,但它并不重要; 只要有接口,这就是我们关心全部这就是我们可以向用户提供有关参数有用的信息f(number => number => number)funcf

“对于这样的功能,这将非常令人困惑:

foo(cb: (number, number) => (number, string) => boolean)

它是做什么的?” -工会

此处使用相同的确切推理。除了(cb: (number, number) => (number, string) => boolean))功能设计不佳的事实(您可以命名几个有用的混合类型四元(4- arity)函数?)外,这也没有关系。f不能假装知道使用此类签名可以提供的无数函数的任何描述符。

所以我的问题是,为什么我必须为函数参数参数指定明显无意义的名称


行使

您可以_用有意义的名称代替吗?

const apply2 = (f: (_: number) => (_: number) => number) => (x: number) => (y: number): number => {
    return f (x) (y)
};

const sqrt = (x: number): number => Math.sqrt(x);
const sq = (x: number): number => x * x;
const add = (addend: number) => (augend: number): number => addend + augend;
const pythag = (side1: number) => (side2: number): number => sqrt(add(sq(side1)) (sq(side2)));

console.log(apply2 (add) (3) (4));    // 7
console.log(apply2 (pythag) (3) (4)); // => 5

如果不是,您能否提出令人信服的论点,为什么在TypeScript签名中必须出现这样的名称

尼桑·托默尔

至少以易读的方式很难编写易变的定义。
我要做的是尽可能地在函数声明之外提取签名,如下所示:

type Ord = string | number;
type ThirdFunction = (objs: Ord[]) => boolean;
type SecondFunction = (objs: Ord[]) => ThirdFunction;
type FirstFunction = (fn: (o: Ord) => (o: Ord) => boolean) => SecondFunction;

const arrayCompare: FirstFunction = f => ([x,...xs]) => ([y,...ys]) => {
    ...
}

操场上的代码

我还删除了declare您在Ord类型别名之前使用的,因此不需要它。您可以为这些类型找到更好的名称。
另一件事是,您无需在boolean此处指定

const eq = (x: Ord) => (y: Ord) : boolean => x === y;

可:

const eq = (x: Ord) => (y: Ord) => x === y;

或者,您可以使用单个type声明来表达该功能考虑到所有因素,可读性相当不错。

type Ord = number | string;

type arrayCompareFunc = (f: (x: Ord) => (y: Ord) => boolean)
                      => (xs: Ord[])
                      => (ys: Ord[])
                      => boolean;

const arrayCompare: arrayCompareFunc = f => ([x,...xs) => ([y,...ys) => {
   ...
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在TypeScript中为函数参数设置参数名称和类型?

在TypeScript中获取函数参数名称和类型

为什么必须在TS函数类型中指定参数名称?

参数名称是否必须为模型?

为什么Typescript函数类型签名包含参数名称

用R中的函数指定参数名称

如何避免函数名称中的参数类型?

我是否必须为每个不同的参数重载函数?

函数名称相同,参数类型不同

在 Go 中打印类型参数名称

为什么必须为Func参数明确指定我的类型参数?

为什么箭头函数名称必须为const / let?

将函数名称文字传递给高阶函数是否安全?

为什么我的函数不接受Colors类型的参数名称?

从函数声明中收集参数名称

在Python中参数化函数名称

在Python中更改函数参数名称

lua函数调用中的参数名称

从匿名函数中查找参数名称

Kotlin 中的函数参数名称

Typescript推断高阶函数中内部函数的类型

通用高阶函数参数类型

应用函数名称和参数的函数类型

可选参数必须是引用类型,可为空的类型,或者必须声明为可选参数。参数名称:参数`

“值”中的路径必须以“ /”开头。参数名称:值

警告:函数声明中的参数名称(无类型)[默认启用]

如何在TypeScript中编写通用的,类型安全的高阶函数?

在不知道参数名称的情况下,定义在typescript中作为参数传递的对象的参数类型

是否有可能通过javascript中的函数名称获取参数