My idea is to implement a discriminated union using null
as the discriminator:
type Result<T> = { result: T; error: null } | { result: null; error: string }
If the function register()
returns a Result
, I could handle it like this:
const { error, result: user } = await register(fields)
if (error) return typedjson({ fields, fieldErrors: { email: error } })
// All good: user data is accessible
However, TypeScript doesn't appear to be recognizing null
as a discriminator for the union:
https://i.sstatic.net/DlRXl.png
This is puzzling considering that https://github.com/microsoft/TypeScript/pull/27695 indicates that null
should work as a discriminator.
My temporary solution:
Utilize boolean as the discriminator instead:
type Result<T> = { invalid: false; result: T; error: null } | { invalid: true; result: null; error: string }
Nevertheless, this introduces an extra (superfluous) variable in the destructuring statement:
const { invalid, error, result: user } = await register(fields)
if (invalid) return typedjson({ fields, fieldErrors: { email: error } })