简体   繁体   中英

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?

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.

You can us in https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-the-in-operator

if (user.name) { // error
    user // typeof user is User | {}
    user.name // error
    user.email // error 
}

if ('name' in user) {
    user // ok, typeof user is User
    user.name  // string 
    user.email // string
}

tsplayground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM