网站搜索

typescript - 使用联合元组时控制流无法进行类型收窄?


我在使用元组时遇到了问题:

export async function redirectIf(
  nextCookies: NextApiRequestCookies,
  options: { notAuth: PagePath },
): Promise<[Redirect, undefined] | [undefined, UserDto]>;

如果 redirect 不存在,它不会意识到 user 的存在:

操场

答案#1

最新答案

自 TypeScript v4.6 起此问题已修复,详见解构判别联合的控制流分析。

旧答案

感谢 TypeScript 社区 Discord 服务器上的 Gerrit0#7591 回答:


TypeScript 不会跟踪不同变量之间的类型收窄。如果你有:

const x: [true, string] | [false, Error] = ...

然后检查元组的第一个元素,TypeScript 就可以缩小类型范围:

if (x[0]) {
  // TS knows x[1] is a string
}

但是如果你先解构,那么你将有两个(至少在 TypeScript 知道的范围内)完全不相关的变量。

const [isStr, val] = x
if (isStr) {
   // val is string | Error, not string
}

对此没有真正的解决方法,除了不进行解构,或者在充分缩小类型之后再进行解构。

if (x[0]) {
  const val = x[1] // val: string
}