loading...
Cover image for 5 useful TypeScript tricks

5 useful TypeScript tricks

basilebong profile image Basile Bong Updated on ・1 min read

1. Create a type checking function

interface IDog{
   name:  string;
   age: number;
   kidFriendly: boolean;
}

interface ICat{
   name: string;
   age: number;
   activityLevel: number;
}

type Animal = IDog | ICat;

/** Is the animal a dog ? */
const isDog = (animal: Animal) : animal is IDog => (animal as IDog).kidFriendly !== undefined;

if(isDog(animal)){
   console.log(animal.kidFriendly);
}
Enter fullscreen mode Exit fullscreen mode

More information here:

2. Set all properties of an interface to optional

interface IDog{
   name: string;
   age: number;
   kidFriendly: boolean;
}

const dog : Partial<IDog> = {
   name: "Rex"
}
Enter fullscreen mode Exit fullscreen mode

3. Get the type of the parameters of a function

const walkDog = (dogName: string, distance: number) => { /** ... */ }

const params: Parameters<typeof walkDog> = ["Rex", 48];
Enter fullscreen mode Exit fullscreen mode

4. Use Setters and Getters

Setters and Getters also exist in plain JavaScript. Still, they are very useful in TypeScript (and other languages).

class Dog{
   private _name: string = "";

   get name(): string{
      return this._name;
   }

   /** Check the length of the name before setting it **/
   set name(newName: string){
      if(newName.length < 8) {
         throw new Error(`The dog's name needs at least 8 charachters`)
      }

      this._name = newName;
   }
}
Enter fullscreen mode Exit fullscreen mode

5. Optional chaining

Optional chaining has recently been added to JavaScript (ECMAScript 2020).

let cat?: ICat;  

/** With optional chaining **/
let animal = cat?.fur.length;

/** Without optional chaining **/
let cat = cat === null || cat === undefined ? undefined : car.fur.length;
Enter fullscreen mode Exit fullscreen mode

Posted on by:

basilebong profile

Basile Bong

@basilebong

I build web applications with functional and aesthetic interfaces while focusing on user experience, performance and scalability.

Discussion

pic
Editor guide
 

How does the isDog function work since .type is not a valid property? And how does JS know to set the private property .name in the setter instead of calling the setter again?

 

My guess would be that the example is not complete.
You could create an enum like

enum Animaltype = {
dog = "dog",
cat = "cat"
}

and adjust the Interfaces by creating animal as parentinterface:

interface Animal {
 type: AnimalType
}

interface IDog extends Animal {
type: AnimalType.dog
....
}

interface ICat extends Animal {
type: AnimalType.cat
....
}
 

I guess you're right, I also didn't understand how it worked, and I noticed how much code is needed just to determine if an animal is an IDog or an ICat ...

This seems so basic, but no, we need to write something like:

const isDog = (animal: Animal) : animal is Dog => animal.type === "dog";

I don't even understand the "animal is Dog" construct before the arrow, what is that? ... and now it seems that in fact we also have to add an enum to make it work :-)

I can't believe that we need this much boilerplate for something so trivial ... why doesn't TS simply let us write const isDog = animal is IDog; or something like that?

The concept is called typeguard and its basicly that you telling TS a condition under which an animal will be a dog since TS can't infer it sometimes by itself.

You could modify the example by writing something like:

enum Animaltype = {
dog = "dog",
cat = "cat"
}

interface BaseAnimal {
 type: AnimalType
}

interface IDog extends BaseAnimal {
type: AnimalType.dog
....
}

interface ICat extends BaseAnimal {
type: AnimalType.cat
....
}

type Animal = ICat | IDog

if you then have something beeing typed as animal a simple if-statement would be enough to determine the type

if(animal.type === AnimalType.dog) {
// all dog specific attributes should now be typesafe
}

Thanks, I vaguely remember type guards ... such a complex beast, Typescript, I've done one toy project with it, and yes you can produce some pretty elegant code if you put in the necessary effort, but it really requires an investment ... I'm still baffled that we have JS and then we put a typed language on top of it which is 5 times more complex than JS and takes at least 3 times longer to master, and all the while people are still disagreeing on its benefits.

IMO typescript once you know some of the pitfalls can become a super strong tool too determine bugs before you hit refresh without having too much overhead in typing. Its also great while refactoring since you see most of the bugs right away and don't need to search them.

Yes absolutely, it shines with refactoring and especially with autocomplete in an IDE like VSCode (you benefit from that even when you don't use TS but your libraries/imports do) ... and what I liked is that your code "documents itself" and that it makes you think a bit more thoroughly about code design.

 

I suppose that since that piece of code is within the scope of the setter it will assume that .name is the property, and not the setter itself?

 

I edited the setter/getter example. It will work properly and be more clear.

 

I believe setters and getters are already available in plain javascript.

 

Hi,
Indeed Setters and Getters also exist in plain JS. Note that optional chaining has also been recently added to JS.
Thanks for the comment, I will edit my post to make this clear!

 

Hi Basile thanks for sharing.
Can you explain the firsr example a little more.
It is very interesting.
Best regards..

 

Hi Nader,
I created a new post to make the concept of User-Defined Type Guards (showed in the first example) easier to understand. Let me know if you have any questions.