On the world of TypeScript we have two properties that are smarter than you think, this thing is the Union Types
and Type Guards
and I'll talk a little bit about the bellow
Union Types
In javascript development, there are a few moments when you will have to deal with two or more types of information in your parameter or variable, that's where the union types
comes into play. As the name implies, this guy will perform the theoretical merge of the types we pass to him, to declare a type union, we use the pipe character, as in the example below
// Variable
let myWonderfulVariable: number | string;
// Function
const myFunction = (info: string | number): void => {}
But if you think you just define the types you want and quit using, you're wrong. Under the hood, TypeScript will perform a verification of the types you entered and will make available ONLY the methods that are common among the informed types, let's take the example of its function just above...
The same is true of any interface or type you may have...
Type Guards
Directly speaking, we can say that type guards
allows you to restrict the type of content to a conditional block, where we can perform these checks using some operators which I will comment below
typeof
It allows you to perform verification according to the primitive types we have, namely: number, string, boolean and symbol
const myFunction = (x: number | string): void => {
if (typeof x === 'number') {
console.log('The variable X it\'s like a number')
}
if (typeof x === 'string') {
console.log('The variable X it\'s like a string')
}
}
But now you may be wondering, why does typeof only work with the primitive values I commented above? Look at this...
When you try to compare something other than a number, string, boolean, or symbol, JavaScript ends up returning it as an object 🙃
instanceof
It allows you to perform a check of any variable that was created through a constructor
class Company {
companyName: string;
companyAddress: string;
location: {
lat: number;
lng: number
}
}
class User {
userName: string;
userAddress: string;
location: {
lat: number;
lng: number
}
}
const myFunction = (x: Company | User): void => {
if (x instanceof Company) {
console.log('The variable X it\'s a instance of Company')
}
if (x instanceof User) {
console.log('The variable X it\'s a instance of Company')
}
}
in
Checks if a property exists in the given context
interface Company {
companyName: string;
}
interface User {
userName: string;
}
const myFunction = (x: Company | User): void => {
if ('companyName' in x) {
console.log('The `companyName` exists on variable X')
}
if ('userName' in x) {
console.log('The `userName` exists on variable X')
}
}
References
If you liked the topic and want to dig deeper, I recommend some sources to dig deeper into not only the subject here, but also TypeScript as a whole:
- TypeScript Deep Drive
- Typescript: The Complete Developer's Guide
- TypeScript Documentation: Advanced Types
Today's content is based on my journey to learning TypeScript and it's also my first post here 🎉, follow me on twitter (@pauloedurezende ) if you want to give me feedback (they are always welcome 🤗)
Top comments (2)
If we have
How can we do this…?