typescript - 从只读元组类型中过滤掉值
问题描述
我在编写一个辅助类型时遇到了一些麻烦,它接受一个元组Parser<T>
作为参数并返回一个T
s 的元组类型,除了 when T
is undefined
。
这是我到目前为止所拥有的:
class Parser<T> {}
type ToSequenceValueType<P extends ReadonlyArray<Parser<any>>> =
P extends [infer P, ...infer R]
? P extends Parser<infer V>
? V extends undefined
? ToSequenceValueType<R>
: [V, ...ToSequenceValueType<R>]
: never
: []
type A = readonly [Parser<number>, Parser<string>, Parser<undefined>, Parser<boolean>]
type R = ToSequenceValueType<A> // Should be [number, string, boolean]
但是递归调用 ( ToSequenceValueType<R>
) 被下划线标记为错误,它显示:
Type 'R' does not satisfy the constraint 'readonly Parser<any>[]'
我应该怎么做 ?
解决方案
我相信你正在寻找这个解决方案:
class Parser<T> { }
/**
* I'm using square brackets for [Val] to avoid distributivity
*/
type MapPredicate<T> =
T extends Parser<infer Val>
? [Val] extends [undefined]
? []
: [Val]
: never;
type Mapped<
Arr extends ReadonlyArray<Parser<any>>,
Cache extends ReadonlyArray<unknown> = readonly []
> =
/**
* If argument is empty array - return empty array
*/
Arr extends readonly []
? readonly []
/**
* This should be the last call of recursion
* I just adding last element of an array to Cache
*/
: Arr extends readonly [infer H]
? [...Cache, ...MapPredicate<H>]
/**
* If array contains more than one element
* I call Mapped with Tail (all elements but the first)
* an adding first element (Head) to cache
*/
: Arr extends readonly [infer Head, ...infer Tail]
? Tail extends ReadonlyArray<Parser<any>>
? Mapped<[...Tail], [...Cache, ...MapPredicate<Head>]>
: never
: Cache;
type P = Parser<number>;
type A = readonly [Parser<number>, Parser<string>, Parser<undefined>, Parser<boolean>]
type R = Mapped<A> // [number, string, boolean]
因为您想ToSequenceValueType
递归调用 ->P
并不总是会扩展[infer P, ...infer R]
,所以最后两次调用它将扩展空数组和带有一个元素的数组。
如果MapPredicate<H>
返回空数组[]
,...MapPredicate<H>
则计算结果为空,这就是我过滤undefined
值的方式
推荐阅读
- bash - 如何从模式生成 n 个字符串(即二十个)?
- r - FD 包的问题,在函数“functcomp”中
- javascript - 我正在尝试为每个问题创建一个带有一些选项的问题库
- c++ - HashTable With Double Hash - Contains 方法的标准实现
- mysql - 选择 json 提取的 MySQL 更新
- html - 子 div 有一个偏移边框
- javascript - 如何等到发布方法完成Angular
- linux - Edge TPU 编译器
- reactjs - 尝试设置选项卡导航器时出错
- snowflake-cloud-data-platform - 我们可以在 UDTF 中使用标识符函数,其参数来自 Snowflake 中的 UDTF 参数吗?