Typescript classes, methods, functions and other gotchas
Tags: javascript, typescript
Published: 2020-08-15 21:03:21

---
title: Typescript classes, methods, functions and other gotchas
published: true
description: Learning in public about the typescript constructs
tags: #JavaScript #typescript 
cover_image: https://aaronlam.us/typescript-part2/meme.png
---

Hi friends!

This post is a bit different from the others I've made in that I'm not going to be talking about practical ways/ tips & tricks on how to become a better developer or tech person. 

The idea for this post was sparked as I was working on a demo project at work and I was fiddling around with the online Typescript compiler. 

There are some interesting things I discovered but I think I might may be missing something so I thought about sharing it with the community and be a way like @swyx says to 'learn in public'.

So here it goes!

![Jumping in](https://media.giphy.com/media/xT9IgMjmgWhVqQQ47u/giphy.gif)

## The scenario

In Typescript there's the class construct that contains properties, methods and a constructor. So we could do something like this:

```javascript
class Person {
    name: string;
    age: number;

    constructor(personName: string, personAge: number) {
        this.name = personName;
        this.age = personAge;
    }
}
```

And compiled to ES2015 it will give me the following.

```javascript
class Person {
    constructor(personName, personAge) {
        this.name = personName;
        this.age = personAge;
    }
}
```

So that works and now if I want to add a method to the class to go along with those properties I'd do this:

```javascript
class Person {
    name: string;
    age: number;

    constructor(personName: string, personAge: number) {
        this.name = personName;
        this.age = personAge;
    }

    greet(): string {
        return `Hello! my name is ${this.name}`;
    }
}
```

And then the compiler will give me the following:

```javascript
class Person {
    constructor(personName, personAge) {
        this.name = personName;
        this.age = personAge;
    }
    greet() {
        return "Hello! My name is " + this.name;
    }
}
```

Now all that works, inside the constructor I can refer to the properties of the class using the `this` keyword, like `this.name`.
And with that constructor in place I can now instantiate the class and create a 'Person' object like this:

```javascript
const person1 = new Person("Max", 25);
```

And now this is awfully reminiscent to Java... 
Anyway, after that I can now access the greet function like this:

```javascript
console.log(person1.greet());
```

And that will print to the console "Hello! my name is Max".

But now is when it gets very interesting. We established that besides the constructor, all a class has are properties and methods. 

The properties are Typescript types and the methods are functions. Like in the constructor, we access the class properties using the `this` inside the methods like in the greet method when accessing the person's name. 

But then I thought that it looks very plain. The function doesn't receive any parameters and doesn't do more than just returning a string with the name property. 

What if I change it to a more succinct way? By the way, I'm aware of the fact that traditional functions create their own internal scope and handle the `this` in an particular way as opposed to arrow functions which inherit the `this` from the parent.

But if I have the functions already inside a class then I'm referring to the properties of the class as a whole, so no weird `this` behaviors in this case. 

Knowing that, I can go about rewriting the greet function like this:

```javascript
this.greet = () => `Hello! my name is ${this.name}`;
```

That still works when logging the person's name. Except for the fact that now the Person class gets changed by the compiler into this: 

```javascript
class Person {
    constructor(personName, personAge) {
        this.name = personName;
        this.age = personAge;
        this.greet = () => "Hello! My name is " + this.name;
    }
}
```

Ok. Now _that's_ something different. Not only logging the result of the greet function is the same, but I can even use the `export` keyword and call that method from a different class defined in a different file like this:

```javascript
class Employee {
    empInfo: Person;
    role: string;

    constructor(role: string) {
        this.role = role;
    }

    fullGreeting(): string {
        return `${this.empInfo.greet()} and my role is ${this.role}`;
    }
}
```

And this will still work just fine. 

So the behavior is the same but the fundamental change is that the function greet went from being a method of the class to become a property itself. 

Also the Intellisense in VSCode would tell me just that, it is a property of the class that gives me back a string value.

I actually converted all the functions of a service class for a small project I was working on into these kind of properties and kept on building the thing like that. 

Ultimately, I changed it to the originally version 'cause I realized that this way might not be the most intuitive for others when looking at the code. And we know that it is better to write readable code instead of being all 'smarty pants' with the stuff that we write.

Still, this interesting finding kept doing rounds in my head and I thought is that all? 

Could there be more to this that I'm not aware of and I might be discounting just because 'it works'?

That's the whole deal right here. Typescript with some quirks of its own as well. I'm sure this would get even more quirky if it would be converted into ES5 or lower hahaha fun stuff to discover.

---
That's it for this post. Any comments or feedback on this is greatly appreciated. 

Thanks for reading so far and I hope to see you (_or read you_) in the next one.