Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript: Discriminated Union with empty object

I have the following type User:

type User = {
    name: string;
    email: string;
} | {};

So essentially a user can be an object with name and email properties, or the empty object.

When I try to check which of the two a given user object is, TypeScript shows an error.

if (user.name) { // ERROR
    // do something if user object is populated
}

Specifically the above code throws the error:

Property 'url' does not exist on type 'PrismicImage'.
Property 'url' does not exist on type '{}'

Is it possible to have a discriminated union where one of the interfaces is the empty object?

like image 854
Stud Sterkel Avatar asked Aug 30 '25 17:08

Stud Sterkel


1 Answers

A discriminated union (as the term is commonly understood in TypeScript) is a union in which there is a discriminant property that exists on every member of the union with a different value. So a union including {} is, by definition, not a discriminated union. If you are willing to change your design to use a discriminated union, everything should work.

Re your current design: In general, a TypeScript object type includes any object that has at least the specified properties. That means {} is effectively the type of any object, and your User type just simplifies to {}. There is no (reasonable) way to express the type of an object with no properties; this suggestion might add one. You'll have to cast your object before you can test the name property, and even after you test the property, I'm not aware of any way to make TypeScript automatically know that the email property also exists. You could at least define a user-defined type guard to hide all the mess in one function.

like image 171
Matt McCutchen Avatar answered Sep 02 '25 07:09

Matt McCutchen