如何使用参数转发来注释高阶函数
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 的新手,此示例依赖于 Generics and Rest Parameters. Specifically, Rest Generics in this example were added in 3.0。
提出以下解决方案:
// @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 的参数。但至少类型检查工作正常
感谢大家的回答
这里是流程版本:
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
(Try)
我正在尝试为这篇作文添加注释:
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 的新手,此示例依赖于 Generics and Rest Parameters. Specifically, Rest Generics in this example were added in 3.0。
提出以下解决方案:
// @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 的参数。但至少类型检查工作正常
感谢大家的回答
这里是流程版本:
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
(Try)