I have an issue with tuples:
export async function redirectIf(
nextCookies: NextApiRequestCookies,
options: { notAuth: PagePath },
): Promise<[Redirect, undefined] | [undefined, UserDto]>;
It is not aware that the user
exists if redirect
does not:
This has been fixed since TypeScript v4.6, see Control Flow Analysis for Destructured Discriminated Unions.
Thanks to Gerrit0#7591 on the TypeScript Community discord server who answered:
TypeScript does not track narrowing across separate variables. If you have:
const x: [true, string] | [false, Error] = ...
And check the first element of the tuple, then TS can narrow down the type:
if (x[0]) {
// TS knows x[1] is a string
}
But if you destructure first, then you have two (as far as TS knows) totally unrelated variables.
const [isStr, val] = x
if (isStr) {
// val is string | Error, not string
}
There's no real workaround to this besides not destructuring, or doing destructuring after having narrowed the type sufficiently.
if (x[0]) {
const val = x[1] // val: string
}