在 TypeScript 中指定变量参数的可变参数泛型参数的顺序

问题描述 投票:0回答:1

我正在尝试做一些感觉荒谬的事情,但我已经非常接近了,我觉得它一定是可能的,我只是不太明白。

我正在尝试创建一个通用函数类型,以便分配函数类型

const typedFunction: Generic<
    SomeObject,
    ['keys', 'in', 'that', 'object']
>;

将生成一个函数,其参数的类型准确:

(
    arg0: typeof SomeObject['keys'],
    arg1: typeof SomeObject['in'],
    arg2: typeof SomeObject['that'],
    arg3: typeof SomeObject['object']
)

我已经找到了两个接近但不完全的解决方案;

1.

declare type SomeGeneric<
   T,
   Params extends (T[keyof T])[]
> = (...args: Params) => ReturnType;

这保留了顺序,但迫使我以一种非常丑陋的方式指定参数:

const someFunction: SomeGeneric<
    SomeObject,
    [SomeObject['keys'], SomeObject['in'], ...]
> = (arg0, arg1, arg2, arg3) => { ... };

这显然冗长到无用的程度,因为我可以直接这样指定它们。

2.

declare type SomeGeneric<
    T,
    Params extends (keyof T)[]
> = (...args: T[Params[number]][]) => ReturnType;

但是,由于

Params[number]
引用 Params
any
成员,这会将
SomeGeneric<SomeObject, ['keys', 'in', 'that', 'object']>
的每个参数转换为
SomeObject['keys'] | SomeObject['in'] | ...

的联合类型

我想知道的是,是否有某种方法可以指定我希望通过提供的键按顺序访问

SomeObject
,例如...args: SomeObject[...Params[number]](如果这种语法不是无意义的话)。
    

typescript generics variadic
1个回答
1
投票

您需要使用

映射类型

来映射Params中的元素。对于每个索引

I
,您可以获得数组元素
Params[I]
,可用于
T
请注意,从 

3.1

开始,使用映射类型来映射元组也会生成元组。这在这里很重要,因为扩展参数类型必须是元组类型。 declare type SomeGeneric< T, Params extends (keyof T)[] > = (...args: { [I in keyof Params]: T[Params[I]] }) => void; type Test = { a: string b: number c: Date } const someFunction: SomeGeneric<Test, ["a", "b", "c"]> = ( arg0, // string arg1, // number arg2 // Date ) => {}


游乐场

© www.soinside.com 2019 - 2024. All rights reserved.