繁体   English   中英

如何使用参数转发注释高阶函数

[英]How to annotate high order function with arguments forwarding

我正在尝试注释此组成:

const get1 = (n: number, s: string) => `${n}_${s}`;
const get2 = (s: string, n: number) => `${n}_${s}`;

const foo = (get) => (...args) => {
    get(...args);
}

const foo1= foo(get1);
const foo2= foo(get2);


foo1(2, 'qwe');
foo2('qwe', 1)

目前,我正在使用Flow作为类型检查器,但我对TypeScript的答案也很感兴趣,因为这对我来说是一个很好的迁移点。

您可以在此示例中使用以下方法:

const get1 = (n: number, s: string) => `${n}_${s}`;
const get2 = (s: string, n: number) => `${n}_${s}`;

const foo = <T extends any[], R>(get: (...args: T) => R) => (...args: T): R => {
  return get(...args);
};

const foo1 = foo(get1);
const foo2 = foo(get2);

foo1(2, "qwe");
foo2("qwe", 1);

TypeScript游乐场

如果您是TypeScript的新手,则此示例依赖于GenericsRest Parameters 具体而言,此示例中的Rest Generics在3.0中添加了。

这是流程版本:

const get1 = (n: number, s: string) => `${n}_${s}`;
const get2 = (s: string, n: number) => `${n}_${s}`;

const foo = <A: mixed[], R>(get: (...A) => R): ((...A) => R) => 
  (...args: A): R =>
    get(...args);

const foo1= foo(get1);
const foo2= foo(get2);


foo1(2, 'qwe');
foo2('qwe', 1);
// $ExpectError
foo1('qwe', 2);
// $ExpectError
foo2(2, 'qwe');

foo2('qwe', 1, 3); // this should probably error but doesn't

尝试

提出以下解决方案:

// @flow

const get1 = (n: number, s: string) => `${n}_${s}`;
const get2 = (s: string) => `_${s}`;

type Apply<T, R> = (...args: T) => R

const foo = <TArgs: *>(get: Apply<TArgs, string>): Apply<TArgs, Promise<*>> =>
    (...args) => {
        const str = get(...args);

        return Promise.resolve(str);
    }


const foo1= foo(get1);
const foo2= foo(get2);


foo1(1, 'qwe');
foo2('qwe');

// $ExpectError      
foo2('qwe', 'qwer') //wrong arity
// $ExpectError 
foo2('qwe', 2, 3, 5, 6, 4) //wrong arity
// $ExpectError 
foo1(1, 'qwe', 3, 5, 6) //wrong arity

这个示例还有一个附加功能,我不返回get的结果,而只是在函数内部使用它。

看起来它几乎可以正常工作。 缺少的一件事是foo1和foo2的相似性。 但是至少类型检查可以正常工作

谢谢大家的回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM