如何使 TypeScript 从数组中推断参数的数量和类型
How to make TypeScript infer number & types of arguments from an array
我尝试创建一个非常简单的函数来接受:
- 回调
- 要传递给回调的可选参数数组
普通 JS 中的函数如下所示:
const callCallback = (cb, args = []) => cb(...args);
回调可能会接受任意数量的参数以及 return 任何参数。问题是我无法用 TypeScript 正确表达回调类型。我试图像这样声明 callCallback
的类型(想法是推断回调的参数和 return 类型):
export interface CallCallback {
<CbReturn, CbArgs>(
cb: (...optionalArguments: CbArgs[]),
args?: CbArgs[],
): CbReturn
};
但是,这没有用,因为它强制回调使用参数传播语法,而这不是我打算做的。
我也找到了 this answer 但至于现在 TS 不允许我将传播参数设为可选。
如何将 args
数字和类型推断为 cb
参数列表?
下面的方法行得通吗?看起来您实际上是在输入 apply
:
interface ApplyFn {
<F extends () => any>(fn: F): ReturnType<F>;
<F extends (...args: any[]) => any>(fn: F, args: Parameters<F>): ReturnType<F>;
}
declare const apply: ApplyFn;
apply((f: number, s: string, t: Date) => f + s + t, [23, "two", new Date]); // OK
apply((f: number, s: string, t: Date) => f + s + t, ["not a number", "two", new Date]); // ERR
apply((f: number, s: string, t: Date) => f + s + t, [123, "two"]); // ERR
apply(() => "nice!", []); // OK
apply(() => "nice!"); // OK
apply((param: number) => "nice!"); // ERR
编辑:如果您有适合此类函数的孔(例如,函数参数),则上述类型很有用。如果您实际上是在尝试定义此函数,则将其表示为标准函数定义会更容易:
function apply<F extends () => any>(fn: F): ReturnType<F>;
function apply<F extends (...args: any[]) => any>(fn: F, args: Parameters<F>): ReturnType<F>;
function apply(fn: Function, args: any[] = []) {
return fn(args);
}
我尝试创建一个非常简单的函数来接受:
- 回调
- 要传递给回调的可选参数数组
普通 JS 中的函数如下所示:
const callCallback = (cb, args = []) => cb(...args);
回调可能会接受任意数量的参数以及 return 任何参数。问题是我无法用 TypeScript 正确表达回调类型。我试图像这样声明 callCallback
的类型(想法是推断回调的参数和 return 类型):
export interface CallCallback {
<CbReturn, CbArgs>(
cb: (...optionalArguments: CbArgs[]),
args?: CbArgs[],
): CbReturn
};
但是,这没有用,因为它强制回调使用参数传播语法,而这不是我打算做的。
我也找到了 this answer 但至于现在 TS 不允许我将传播参数设为可选。
如何将 args
数字和类型推断为 cb
参数列表?
下面的方法行得通吗?看起来您实际上是在输入 apply
:
interface ApplyFn {
<F extends () => any>(fn: F): ReturnType<F>;
<F extends (...args: any[]) => any>(fn: F, args: Parameters<F>): ReturnType<F>;
}
declare const apply: ApplyFn;
apply((f: number, s: string, t: Date) => f + s + t, [23, "two", new Date]); // OK
apply((f: number, s: string, t: Date) => f + s + t, ["not a number", "two", new Date]); // ERR
apply((f: number, s: string, t: Date) => f + s + t, [123, "two"]); // ERR
apply(() => "nice!", []); // OK
apply(() => "nice!"); // OK
apply((param: number) => "nice!"); // ERR
编辑:如果您有适合此类函数的孔(例如,函数参数),则上述类型很有用。如果您实际上是在尝试定义此函数,则将其表示为标准函数定义会更容易:
function apply<F extends () => any>(fn: F): ReturnType<F>;
function apply<F extends (...args: any[]) => any>(fn: F, args: Parameters<F>): ReturnType<F>;
function apply(fn: Function, args: any[] = []) {
return fn(args);
}