我正在尝试将函数的参数分配给类型别名。例如。为此功能
function foo<T>(bar: T, baz: number) {}
我想获取其参数的签名。通常我会这样做
type FooParams = Parameters<typeof foo>;
但是问题在于导致
的签名[{}, number]
这很有意义,因为我没有指定T
是什么。但是,我希望这能起作用
type FooParams<T> = Parameters<typeof foo<T>>; // hopefully [T, number]
但事实并非如此,只会导致大量语法错误。
是否可以正确获取泛型函数的参数列表的类型?
答案 0 :(得分:1)
您可以使用该infer
关键字:
type Args<T> = T extends (...args: infer I) => any ? I : never;
type R = Args<(args: number, arg: string) => number >;
// R = [number, string]
这意味着类型I
被视为泛型,但您不必像这样声明:let fn = <T>(arg:T): T {...
-----编辑------
您可以实现泛型类型,但必须声明函数的类型:
type Foo<T> = (bar: T, baz: number) => void;
type R2<Placeholder> = Args<Foo<Placeholder>>; // [Placeholder, number]
type R3 = R2<boolean> // [boolean, number]
答案 1 :(得分:0)
我的解决方案只是一种可能有帮助的解决方法。这不是你想要的
这里你有非通用的解决方案。我的意思是它只适用于 foo
类型签名
function foo<T>(bar: T, baz: number) { }
type Fn = (...args: any) => any
type Tail<T extends any[]> = T extends [infer _, ...infer Rest] ? Rest : never
type ReplaceFirstParameter<F extends Fn, Fst> =
(fst: Fst, ...args: Tail<Parameters<F>>) => ReturnType<F>
type Foo<T> = ReplaceFirstParameter<typeof foo, T>
type Result = ReplaceFirstParameter<typeof foo, number> // (fst: number, baz: number) => void
这个解决方案是最通用的。它将用提供的通用参数替换所有 unknown
参数。
我假设每个泛型函数都是未知的——这是弱点。
type MapPredicate<T, V> = T extends unknown ? V : T
type ReplaceUnknown<
Arr extends Array<unknown>,
Value,
Result extends Array<unknown> = []
> = Arr extends []
? []
: Arr extends [infer H]
? [...Result, MapPredicate<H, Value>]
: Arr extends [infer Head, ...infer Tail]
? ReplaceUnknown<[...Tail], Value, [...Result, MapPredicate<Head, Value>]>
: Readonly<Result>;
function foo<T>(bar: T, baz: number) { }
type Fn = (...args: any) => any
type ReplaceParameters<F extends Fn, Value> =
(...args: ReplaceUnknown<Parameters<F>, Value>) => ReturnType<F>
type Result = ReplaceParameters<typeof foo, number> // (fst: number, baz: number) => void