【问题标题】:Is there a user defined typeguard for requiring elements in an array?是否有用户定义的类型保护来要求数组中的元素?
【发布时间】:2021-06-05 12:07:45
【问题描述】:

我正在寻找一个用户定义的类型保护,它将确定一个数组是否包含可为空的或可选的元素。我为RequiredArray写了一个辅助类型:

type RequiredArray<A extends readonly any[]> =
    A extends [infer P, ...infer R]
    ? [NonNullable<P>, ...RequiredArray<R>]
    : []

这似乎有效。但是,当我尝试为它编写类型保护时......

function arrIsFullyDefined<Arr extends readonly any[]>(arr: Arr): arr is RequiredArray<Arr> {
    return arr.every((e) => e !== null && e !== undefined);
}

Typescript 抱怨可能会实例化不同的类型:

A type predicate's type must be assignable to its parameter's type.
  Type 'RequiredArray<Arr>' is not assignable to type 'Arr'.
    'RequiredArray<Arr>' is assignable to the constraint of type 'Arr', but 'Arr' could be instantiated with a different subtype of constraint 'any[]'.
      Type '[] | [unknown]' is not assignable to type 'Arr'.
        '[] | [unknown]' is assignable to the constraint of type 'Arr', but 'Arr' could be instantiated with a different subtype of constraint 'any[]'.
          Type '[]' is not assignable to type 'Arr'.
            '[]' is assignable to the constraint of type 'Arr', but 'Arr' could be instantiated with a different subtype of constraint 'any[]'.
              Type '[]' is not assignable to type 'Arr'.
                '[]' is assignable to the constraint of type 'Arr', but 'Arr' could be instantiated with a different subtype of constraint 'any[]'.ts(2677)

起初我认为这是一个潜在的无限数组类型被分配给Arr 泛型的问题,但是在RequiredArray 类型中检查这个(使用来自typescript-tupleIsFinite)给出了相同的结果. 我的问题是:

  1. 为什么会导致错误?
  2. 如何为这个助手编写类型保护?

【问题讨论】:

  • arr is Arr &amp; RequiredArray&lt;Arr&gt;
  • @LindaPaiste 非常感谢。你知道我怎么能要求 Arr 类型是一个元组吗?现在它也接受数组 (any[])。我需要它只接受[1,2,3],而不是(1|2|3)[]

标签: arrays typescript tuples typescript-generics


【解决方案1】:

感谢 Linda 的解决方案:

type _RequiredArray<Arr extends readonly any[]> =
    Arr extends [infer P, ...infer R]
    ? [NonNullable<P>, ..._RequiredArray<R>]
    : [];

type RequiredArray<Arr extends readonly any[]> = Arr & _RequiredArray<Arr>;

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 2021-04-04
    • 2015-12-19
    • 2018-01-03
    • 2019-02-07
    • 1970-01-01
    • 2019-01-03
    • 2018-03-26
    • 2018-04-13
    相关资源
    最近更新 更多