How to add final to variables and methods in typescript?

Java provides the final keyword for variables, methods, and classes to specify immutability.

Does TypeScript have the final keyword? No, TypeScript does not include a final keyword by default, but there are ways to achieve similar functionality.

One approach is to utilize the readonly keyword for variables, while another involves employing decorators to prevent modification. You can also check Typescript classes and objects

TypeScript Final Variable

In TypeScript, the final behavior for variables is achieved by using the readonly keyword, ensuring that the variable is only assigned once, typically during object construction. readonly is introduced in that allows to initialization of the variable at declaration or constructor.

In the below example,

  • id, name, and company are members of the Employee class
  • constructor contains id with readonly, which means it assigns the value one time during object creation. It throws Compilation Error `Cannot assign to ‘id’ because it is a read-only property. Other fields’ names and companies can be assigned many times.

Here is a typescript final variable example.

class Employee {
  constructor(
    readonly id: number,
    public name: String,
    public company: String,
  ) {}
}

let emp: Employee = new Employee(1, "John", "abc corp");

emp.id = 12; //Error Cannot assign to 'id' because it is a read-only property.(2540)

emp.name = "john";
emp.company = "z corp";

console.log(emp.id, emp.name, emp.company);

While TypeScript does have a const keyword for variables, it cannot be applied to class member variables.

TypeScript Final Methods

In TypeScript, final methods are those that cannot be overridden in extended classes. This can be achieved using decorators to mark methods as final.

In the below example,

  • Create a final decorator that does not allow writable, ie. readonly
  • Superclass has a method that is annotated with @final decorator.
  • Extend the superclass and override the final method
  • It does not throw at compile time.
  • At runtime, It throws Cannot assign to read only property ‘meow’ of object ‘#<Lion>
  • Subclasses do not override the final methods in the parent class Here is a Typescript final methods example
function final(
  target: Object,
  key: string | symbol,
  descriptor: PropertyDescriptor,
) {
  descriptor.writable = false;
}

class Animal {
  eat() {
    console.log("Animal Eat");
  }
  @final
  meow() {
    console.log("Animal Eat");
  }
}
class Lion extends Animal {
  eat() {
    console.log("Lion Eating");
  }
  meow() {
    console.log("Not Implemented");
  }
}

let lion = new Lion();
lion.eat(); // works
lion.meow(); // does not works, Runtimeerror

In this example, attempting to override a method marked as final results in a runtime error.

Conclusion

In conclusion, we’ve explored how to implement final keyword behavior in TypeScript for both variables and methods, providing immutability and preventing method overriding where necessary.