提问人:hassan salehi 提问时间:12/23/2022 更新时间:12/26/2022 访问量:70
如何根据打字稿中参数的索引是偶数还是奇数来限制函数参数类型?
How to restrict function parameters types base on if the index of parameter is even or odd in typescript?
问:
我正在寻找的是有一个具有无限数量参数的函数,并且每个参数类型都基于其索引是偶数还是奇数。
一个人为的例子:
flow(isMachineReady(), 'and', isWaterHot(), 'or', isMilkHot(), 'then', serveCoffee())
奇数参数: 偶数参数:() => boolean
'and' | 'or' | 'then'
因此,如果像这样使用该函数,我想为第二个参数类型获取错误:
flow(isMachineReady(), **isWaterHot()**, 'or', isMilkHot(), 'then', serveCoffee())
这是我之前尝试过但没有奏效的方法
type FlowArgCouple = [operand: () => boolean, operator: 'and' | 'or' | 'then']
function flow(...args: [...FlowArgCouple][]){
...
}
答:
1赞
Dimava
12/23/2022
#1
游乐场
但是 srsly 考虑一些其他结构
import { F } from "ts-toolbelt"
// [T1] or [T1, T2, T1] or [T1, T2, T1, T2, T1]
type ToOddEvenOdd<A extends any[], T1, T2, P extends any[]> =
| A extends [] ? [...P, T1]
: A extends [infer F extends T1] ? [...P, F]
: A extends [infer F extends T1, infer S extends T2, ...infer L] ? ToOddEvenOdd<L, T1, T2, [...P, F, S]>
: A extends [infer F, infer S, ...infer L] ? ToOddEvenOdd<L, T1, T2, [...P, T1, T2]>
: [[A]]
type ODD = () => boolean
type EVEN = 'and' | 'or' | 'then'
function g<A extends any[]>(
...args:
A extends ToOddEvenOdd<A, ODD, EVEN, []> ? A
:
F.NoInfer< ToOddEvenOdd<A, ODD, EVEN, []> >
) { }
g(() => true)
g(() => true, 'and', () => false)
g(() => true, () => false)
g(() => true, 'and')
g(() => true, () => false, () => false)
g(() => true, 'and', 'and')
0赞
hassan salehi
12/26/2022
#2
不错的一个 Dimava,你的解决方案有效。尽管由于某种原因,打字稿需要时间才能找出错误。
我找到了另一种也行之有效的解决方案。但是同样的问题,并不总是在它出现时立即给你错误。但我也添加了这个答案,以防其他任何遇到相同问题的人可以使用它:
type Operand = () => boolean
type Operator = 'and' | 'or' | 'then'
type ValidRepeatedTuple<
T extends readonly unknown[],
U extends readonly unknown[]
> = U extends readonly []
? U
: readonly [...T, ...(U extends readonly [...T, ...infer R] ? ValidRepeatedTuple<T, R> : [])]
type FlowArgs<U extends readonly unknown[]> = [
...ValidRepeatedTuple<[Operand, Operator], U>,
Operand
]
function flow<U extends unknown[]>(...args: FlowArgs<U>){
}
flow(() => true)
flow(() => true, 'and', () => false)
flow(() => true, () => false)
flow(() => true, 'and')
flow(() => true, () => false, () => false)
flow(() => true, 'and', 'and')
评论