【问题标题】:Typescript infer value from subset of union for conditional type打字稿从条件类型的联合子集中推断值
【发布时间】:2021-01-04 17:29:20
【问题描述】:

我正在寻找有关类型推断的一些帮助,以根据条件类型缩小 TypeScript 中的联合。

我们的 API 采用一组参数并对其进行验证。作为验证过程的一部分,它会将所有值标准化,以便于下游处理。其中一个参数可以是字符串数组或字符串数​​组。规范化后,该值始终转换为字符串数组。

为了避免必须显式写出每个已验证的类型(并维护它们),我试图从传入参数(具有相同的键)和解析值推断出已验证的参数。例如:

type IncomingParams = {
   names: string[] | Array<string[]> | undefined
   ages: string[] | undefined
}

// Post validation the object is the following
type Validated = {
   names: Array<string[]>
   ages: string[]

}

这是我想出的,但它并没有确保当有联合时,它总是解析为一个数组数组。

type ArrayUnion<T> = T[] | T[][];

type Params = {
   names: ArrayUnion<string>
   ages: string[]
}

type ValidatedParams<P> = {
    [K in keyof P]: P[K] extends ArrayUnion<infer U>
        ? U[][]
        : NonNullable<P[K]>;
};

const validated: ValidatedParams<Params> = {} as any;

validated.names // This should be string[][]
validated.ages // This should be string[]

可能是 Typescript 无法区分联合,所以我探索的一个选项是使用 &amp; { readonly _sym: unique symbol } 来唯一标识ArrayUnion,尽管这种方法也没有奏效。

如有任何帮助,我将不胜感激。

TypeScript playground

【问题讨论】:

  • 使用您的代码,如果我将validated.names 分配给一个变量(例如const test = validated.names),它似乎具有预期的string[][] 类型。
  • 嗨@AlbertoRivera,谢谢。我已经把一个操场放在一起了。奇怪的是我得到了我在本地记录的错误,但是使用操场我得到了 string[[] - 但是,ages 属性也是 string[][] 当它应该是 string[]
  • @J-R 根据您在上述评论中提供的信息,它让我相信您的工作区/项目使用的是较旧的 Typescript 版本,无法正确推断类型。尝试将项目/工作区升级到更新的 TS 版本,看看它是否可以解决问题。此外,在发布 TS 问题时包含您的 tsconfig.json 可能会有所帮助,因为有时它可能归结为导致在 Playground 中未显示的意外问题。
  • agesstring[][],因为它确实扩展了 ArrayUnion,因为它是一个数组。另外,在您的用例中,如果 names 预验证是 string[],它应该是 string[][] 后验证吗?
  • 嗨@r3wt 感谢您的建议,我已经在上面包含配置的游乐场链接中重新创建了它。我已经更新了我的本地打字稿版本,它现在反映了操场上的问题。

标签: typescript type-inference


【解决方案1】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多