Transitioning to TypeScript: The Ultimate Starter Guide - Part 7
Tags: typescript, javascript, beginners, programming
Published: 2023-09-06 07:06:03

## TypeScript from JavaScript Part 7 of 7: Decorators and Mixins

Hello again, amazing developers! We have finally reached the last part of our journey from JavaScript to TypeScript. In this concluding part of the series, we will explore the advanced features of decorators and mixins in TypeScript.

As a reminder, this series is tailored for beginner developers who are looking for a starting point and exciting ways to infuse new technology into their programming journey. So, let’s dive right into decorators and mixins!

## 1. Decorators

Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. They provide a way to add annotations and a meta-programming syntax for class declarations and members. Decorators use the form `@expression`, where `expression` must evaluate to a function that will be called at runtime with information about the decorated declaration.

### a. Class Decorators

A Class Decorator is declared just before a class declaration. The class decorator is applied to the constructor of the class and can be used to observe, modify, or replace a class definition.

```typescript
function sealed(constructor: Function) {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
}

@sealed
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
```

In this example, `@sealed` is a class decorator that seals both the constructor and its prototype.

### b. Method Decorators

A Method Decorator is declared just before a method declaration. The method decorator is applied to the Property Descriptor for the method and can be used to observe, modify, or replace a method definition.

```typescript
function enumerable(value: boolean) {
    return function (
        target: any,
        propertyKey: string,
        descriptor: PropertyDescriptor
    ) {
        descriptor.enumerable = value;
    };
}

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }

    @enumerable(false)
    greet() {
        return "Hello, " + this.greeting;
    }
}
```

In this example, `@enumerable(false)` is a method decorator that sets the enumerable property of the `greet` method to `false`.

### c. Property Decorators

A Property Decorator is declared just before a property declaration. The property decorator cannot be used to observe or modify a property descriptor. It is only passed the name of the property.

```typescript
function format(formatString: string) {
    return function (
        target: any,
        propertyKey: string
    ) {
        let _value: any;
        const getter = function () {
            return _value;
        };
        const setter = function (newVal: any) {
            _value = newVal;
        };
        const object = {
            get: getter,
            set: setter,
            enumerable: true,
            configurable: true
        };
        Object.defineProperty(target, propertyKey, object);
    };
}

class Greeter {
    @format("Hello, %s")
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }
}
```

In this example, `@format("Hello, %s")` is a property decorator that applies a format to the `greeting` property.

## 2. Mixins

Mixins are a way of building up classes from reusable components by copying the methods from one class into another, without using inheritance.

### a. Creating Mixins

To create a mixin, you can create a class that implements a new interface that extends the interface of the classes you are mixing in.

```typescript
class Disposable {
    isDisposed: boolean;
    dispose() {
        this.isDisposed = true;
    }
}

class Activatable {
    isActive: boolean;
    activate() {
        this.isActive = true;
    }
    deactivate() {
        this.isActive = false;
    }
}

interface DisposableActivatable extends Disposable, Activatable {}
class SmartObject implements DisposableActivatable {
    constructor() {
        setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
    }

    interact() {
        this.activate();
    }

    // Disposable
    isDisposed: boolean = false;
    dispose: () => void;
    // Activatable
    isActive: boolean = false;
    activate: () => void;
    deactivate: () => void;
}

applyMixins(SmartObject, [Disposable, Activatable]);

const smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000);

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        });
    });
}
```

In this example, `DisposableActivatable` is an interface that extends both `Disposable` and `Activatable`. `SmartObject` is a class that implements `DisposableActivatable`, and `applyMixins` is a helper function that copies the methods from `

Disposable` and `Activatable` into `SmartObject`.

## Conclusion

In this final part of the TypeScript from JavaScript series, we delved deep into the world of decorators and mixins, two advanced features of TypeScript that can help you create more robust and reusable code.

Decorators provide a way to add annotations and a meta-programming syntax for class declarations and members, while mixins are a way of building up classes from reusable components without using inheritance.

Congratulations on completing this series! You are now well-equipped to start your journey as a TypeScript developer. Remember, the key to mastery is practice, so don't stop coding!

Happy coding, everyone! 💻✨

---

That’s a wrap. Thanks for reading.

If you're looking for more premium content and resources to help you start and grow your business, consider subscribing to my [Newsletter](https://innovatesphere.beehiiv.com/).

Want to see what I am working on? Check out my [Twitter](https://twitter.com/abhaysinghr1)