gpt4 book ai didi

typescript - 从元组类型中删除所有可选项目

转载 作者:行者123 更新时间:2023-12-02 01:47:51 25 4
gpt4 key购买 nike

假设我想将一个包含可选项(例如 [1, 2, 3?, 4?])的元组转换为仅包含必需项的数组 -> [1, 2 ]

我想出的如下所示,它永远不会变成所有可选项目,我被困在这里。

type OnlyReq <L extends any []> = {
[K in keyof L]-?: L [K] extends Required <L> [K]  ? L [K] : never
}

type Found = OnlyReq <[1, 2, 3?, 4?]> // [1, 2, never, never]

playground

最佳答案

我的方法是写一个 recursive conditional type (实际上是 tail recursive,所以它适用于 TS4.5+ 中相当长的元组)遍历 tuple直到它发现它的其余部分都是所有可选的

请注意 optional elements in tuple types后面不能跟必需的元素;也就是说,类似于 [1, 2?, 3]是不可能的。因此,如果一个元组有任何 必需的元素,则必须特别需要第一个元素。

这是一个实现:

type OnlyReq<T extends any[], U extends any[] = []> = Partial<T> extends T ? U :
T extends [infer F, ...infer R] ? OnlyReq<R, [...U, F]> : U

我们正在将结果累加到类型参数 U 中(以空元组 [] 开始),所以一旦我们决定停止迭代,我们就返回 U .

支票Partial<T> extends T使用 the Partial<T> utility type提出输入元组的全可选版本。一般来说T extends Partial<T>是真的但是Partial<T> extends T不是,除非T已经与 Partial<T> 相同...换句话说,Partial<T> extends T当且仅当 T是全选的。

如果元组 T是全可选的,那么我们返回 U .另外如果 T是空的我们返回U (如果 T 不能拆分为第一个元素 F 和其余元组 R ,则会发生这种情况)。如果T有第一个元素 F , 然后我们知道它是必需的(否则 T 将是全可选的),我们可以将它推到 U 的末尾元组其余部分的递归调用元组 R .


让我们看看它是否有效:

type Found = OnlyReq<[1, 2, 3?, 4?]>
// type Found = [1, 2]

看起来不错。

另请注意 rest elements in tuple types在同一个测试中也被认为是“可选的”,因此它们也应该被剥离:

type StripRest = OnlyReq<[string, boolean?, ...number[]]> 
// type StripRest = [string]

事实上,非元组数组类型 ( Foo[] ) 等同于仅包含一个剩余元素 ( [...Foo[]] ) 的元组,因此将被转换为一个空元组,这可能是也可能不是您想要的:

type Hmm = OnlyReq<number[]>
// type Hmm = []

我正在考虑 "leading" or "middle" rest elements in tuple types超出这里的范围,因为它们会做一些奇怪的事情而你没有问过它们(我希望它不会出现,因为操纵这些类型很烦人):

type What = OnlyReq<[...string[], number]>
// type What = []
type AlsoWhat = OnlyReq<[string, ...boolean[], number]>
//type AlsoWhat = [string]

Playground link to code

关于typescript - 从元组类型中删除所有可选项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70684030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com