有没有可能在TypeScript中输入一个函数签名,以便函数接受一个展开元组参数的平面列表?哇,这很难用语言来描述。例如:
type Pair = { type: string, value: number };
function makePairs(
t1: string, v1: number,
t2: string, v2: number,
...and_so_on: unknown
): Pair[] {
// ...
}
makePairs('a', 1, 'b', 2, 'c', 3);
// => [
// { type: 'a', value: 1 },
// { type: 'b', value: 2 },
// { type: 'c', value: 3 },
// ]
我对函数体的实现不感兴趣,只是想澄清一下--我只想把像[A, B]
这样的元组转换成像[A, B, A, B, A, B, ...]
这样的可变元组。
问题的第二步是让它在稍微复杂的Pair
定义下工作,例如:
type StrPair = { type: 's', value: string };
type IntPair = { type: 'i', value: number };
type BoolPair = { type: 'b', value: boolean };
type Pair = StrPair | IntPair | BoolPair;
type PairType = Pair['type'];
// => 's' | 'i' | 'b'
type PairOfType<T extends PairType> =
| (T extends 's' ? StrPair : never)
| (T extends 'i' ? IntPair : never)
| (T extends 'b' ? BoolPair : never);
// => PairOfType<'s'> === StrPair
type ValueOfType<T extends PairType> = PairOfType<T>['value'];
// => ValueOfType<'s'> === string
type PairTuple<T extends PairType> = [T, ValueOfType<T>];
// => ['i', 123] ✓
// ['s', 'foo'] ✓
// ['b', 'nope'] ⨉
// etc
// Now I'd like to be able to take something (conceptually) like this:
function makePairs(...t1: PairTuple, ...t2: PairTuple, ...moreTuples: unknown) {
// ...
}
// And generalise to something like this:
function makePairs(...pairs: ...[...PairTuple[]]) {
// ...
}
// ... but obviously neither of those syntaxes work
从本质上讲,我希望避免在调用函数时必须将每一对都 Package 在数组中,因为这似乎是不必要的开销(相信我,在使用这种方法的地方,开销 * 将 * 是显著的)。
有什么想法吗?
1条答案
按热度按时间gg58donl1#
这不是最迷人的答案,也许还有更好的答案,但我相信这符合要求:
不幸的是,
never
类型真的会抛出任何有用的错误消息。我无法找到解决方法,所以要么全有要么全无。要么以A, B, A, B
模式传入参数,要么得到“never”错误,但无法快速找出是哪一个抛出了所有错误。