Typescript:在条件类型中使用元组

svujldwt  于 2022-11-18  发布在  TypeScript
关注(0)|答案(1)|浏览(140)

我尝试为数组函数创建一个类型,它可以根据输入数组是否为空返回不同的类型。
我尝试将条件类型与元组结合使用

第一次尝试

export const lastElement = <T, U extends T[]>(array: U): U extends [T, ...T[]] ? T : null => {
  return array[array.length - 1]
}

上述代码返回以下错误:

Type 'T' is not assignable to type 'U extends [T, ...T[]] ? T : null'.ts(2322)

array.ts(343, 29): This type parameter might need an extends U extends [T, ...T[]] ? T : null constraint.

看起来由于某种原因,TS没有尝试检查条件,而只是将返回类型分配给整个表达式

第二次尝试

export const lastElement = <T, A extends T | null, U extends [A, ...T[]]>(array: U): A extends null ? null : T => {
  return array[array.length - 1]
}

上述代码返回以下错误:

Type 'T | A' is not assignable to type 'A extends null ? null : T'.
Type 'T' is not assignable to type 'A extends null ? null : T'.

同样,TS似乎不理解返回类型中存在条件

问题

是否可以在类型脚本中对类型使用条件类型?是否有方法对元组的元素设置条件?

jogvjijk

jogvjijk1#

我不太清楚你为什么要用两个甚至三个泛型类型。这里只有一个参数。所以一个泛型类型应该就足够了。
在这两个例子中,有多个泛型类型会扰乱你的推理。所以我们只使用一个泛型类型T,它必须是一个数组。我们还使用可变元组语法让TypeScript将T推理为 * 元组 * 而不是 * 数组 *。

export const lastElement = <
  T extends any[]
>(array: [...T]): T extends [...any[], infer U] ? U : null => {
  return array[array.length - 1]
}

在条件中,我们推断T的最后一个元素,如果存在,则返回该元素。

lastElement([]) // null
lastElement(["abc", new Date(), 3]) // number

Playground

相关问题