"null" as discriminator in discriminated union

Advertisements

I’d like to use a discriminated union with null as its discriminator:

type Result<T> = { result: T; error: null } | { result: null; error: string }

So if the register() function returns a Result, I could do this:

const { error, result: user } = await register(fields)
if (error) return typedjson({ fields, fieldErrors: { email: error } })
// Everything went ok: user is available

But this doesn’t work because TypeScript doesn’t seem to be using null as a discriminator for the union:

Which is confusing because https://github.com/microsoft/TypeScript/pull/27695 seems to have added null as a discriminator.

My temporary workaround:

Use boolean as the discriminator:

type Result<T> = { invalid: false; result: T; error: null } | { invalid: true; result: null; error: string }

but this adds one more (unnecessary) variable to the destructuring statement:

const { invalid, error, result: user } = await register(fields)
if (invalid) return typedjson({ fields, fieldErrors: { email: error } })

>Solution :

Your code doesn’t work because empty string is falsy.

you’ll be fine with if (error === null) ... to decriminate the union.

Playground

Leave a ReplyCancel reply