'Typescript property does not exist on union type
This is a situation I have ran into a couple of times, it seems like it should be fairly straightforward, but I can't find a solution that doesn't set the type to any
A function takes one of two different objects as the argument, checks which object has been received, and returns the corresponding field.
This is a simplified version of the problem, but the issue is that the two objects are only distinguishable by their properties(which have no overlap), and I can't access any of the properties, because they're not present on the other type.
type Obj1 = {
message: string
}
type Obj2 = {
text: string
}
const getText = (obj: Obj1 |obj2): string => {
if (obj.message) {
return obj.message
}
return obj.text
}
Solution 1:[1]
You have to narrow down the type. You can do so by using the in operator.
const getText = (obj: Obj1 | Obj2): string => {
if ("message" in obj) {
return obj.message
}
return obj.text
}
Solution 2:[2]
You can cast the object to either Obj1 or Obj2:
type Obj1 = {
message: string
}
type Obj2 = {
text: string
}
const getText = (obj: Obj1 | Obj2): string => {
if ((obj as Obj1).message) {
return (obj as Obj1).message
}
return (obj as Obj2).text
}
Solution 3:[3]
The real answer to this problem according to what the question owner asked is this
But there might be a time you are using your defined type with primitive type in this way the above solution is not going to work as the problem I faced
here is the situation
type Obj1 = {
message: string
}
const getText = (obj: Obj1 |string): string => {
if (obj.message) {
return obj.message
}
return obj.text
}
so this scenario the solution stated above would not be perfect for you, so you might need to use typeof ??
const getText = (obj: Obj1 | string): string => {
if (typeof obj !== 'string') {
return obj.message
}
return obj.text
}
Solution 4:[4]
I recommend typescript-is.
import { is } from 'typescript-is';
...
const getText = (obj: Obj1 | Obj2): string => {
if (is<Obj1>(obj)) {
return obj1.message;
}
return obj2.text;
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Murat Karagöz |
| Solution 2 | Nsevens |
| Solution 3 | Ntwari Clarance Liberiste |
| Solution 4 | Yuki Ito |
