gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-30 20:38:40 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Why do I have to specify parameter names in a TS function type?

(3 个回答)


去年关闭。




尝试使用 TypeScript 弄湿我的脚,但我不断遇到 trouble .安 old function resurfaced today作为练习,我很好奇是否可以将其转换为 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当我最终调用它时会绑定(bind)......
问题
为什么我必须在 TypeScript 中为高阶函数参数提供名称?
它没有任何意义,并且使函数签名变得冗长、丑陋、难以编写和阅读。

更新

"as far as names for parameters, consider a function that takes a callback of -> (number -> number -> number) ->, so based solely on the types your options are: add, subtract, multiply, divide, power, compare of which only one makes sense, now if a callback parameter had a name add: (number -> number -> number) the choice would be obvious"Aleksey Bykov


我很高兴有机会回答这个问题。我可以用 (number -> number -> number) 命名堆更多的函数签名。
  • first , second , mod , min , max
  • 按位函数 & , | , 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成为绑定(bind)标识符。和 xy不提供额外的描述——我想这让我明白了我的观点:它们并不意味着有名称或描述。 f对我们可能使用它的方式零知识,但这并不重要;只要它有 (number => number => number)界面,这就是我们所关心的。这是我们可以提供给 func 用户的最有用的信息。关于 f范围。

    "It would be quite confusing for function like:

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

    What does it do?" - unional


    同样的推理也适用于此。除了 (cb: (number, number) => (number, string) => boolean))是一个设计糟糕的函数(你能说出多少有用的混合类型四元(4元)函数?),这无关紧要。 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]) => {
    ...
    }

    ( code in playground )

    我还删除了 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) => {
    ...
    };

    关于typescript - 我是否必须在 TypeScript 中为高阶函数类型指定参数名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42322251/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com