Reputation: 1990
So take this example:
type GeneralAPIError = {
status: "error";
message: string;
};
type Foo = {
status: string;
whatever: string;
}
function wat(): Foo | GeneralAPIError {
return Math.random() > .5 ? {
status: "error",
message: "noooo"
} : {
status: "success",
whatever: "yayyy"
};
}
const eh = wat();
// This doesn't work
console.log(eh.whatever || eh);
// Neither does this
if(eh.hasOwnProperty("whatever")) {
console.log(eh.whatever)
} else {
console.log(eh);
}
// This does, but the "as" is pretty ugly
if(eh.hasOwnProperty("whatever")) {
console.log((eh as Foo).whatever);
} else {
console.log(eh);
}
What's the best way to declare the return type of wat()
?
In real life it makes an API call that can return one shape of JSON for an error (type GeneralAPIError
) and a different one for success (type Foo
). The error type is reused for lots of similar functions.
The code at the end to say "if an object has a certain key, do this with it" works fine functionally, but TS says:
Property 'whatever' does not exist on type 'GeneralAPIError | Foo'. Property 'whatever' does not exist on type 'GeneralAPIError'.
for the first two examples. It feels like I should be able to type the function return so eh.whatever || eh
works. What am I missing?
Upvotes: 0
Views: 32
Reputation: 2388
You need a user-defined type guard to check what the type is.
type GeneralAPIError = {
status: "error";
message: string;
};
type Foo = {
status: string;
whatever: string;
}
/**
* this type guard checks if the element is of type Foo.
*/
function isFoo(wat: Foo | GeneralAPIError): wat is Foo {
return (wat as Foo).whatever !== undefined;
}
function wat(): Foo | GeneralAPIError {
return Math.random() > .5 ? {
status: "error",
message: "noooo"
} : {
status: "success",
whatever: "yayyy"
};
}
const eh = wat();
console.log(isFoo(eh) ? eh.whatever : eh);
Another approach, if you have a simple case, is to use the in
operator:
type GeneralAPIError = {
status: "error";
message: string;
};
type Foo = {
status: string;
whatever: string;
}
function wat(): Foo | GeneralAPIError {
return Math.random() > .5 ? {
status: "error",
message: "noooo"
} : {
status: "success",
whatever: "yayyy"
};
}
const eh = wat();
console.log("whatever" in eh ? eh.whatever : eh);
Upvotes: 1