What are the advantages of typescript over javascript?

typescript vs javascript

Asked on April 29, 2021 in Website.
Add Comment
  • 1 Answer(s)

    TypeScript’s main benefits:

    1. Class and Module Support
    2. Static Type-checking
    3. ES6 Feature Support
    4. Clear Library API Definition
    5. Build-in Support for JavaScript Packaging
    6. Syntax Similarity to Our Backend Languages (Java, Scala)
    7. Superset of JavaScript

    Class and Module Support

    Keywords like class, interface, extends and module are available in TypeScript.
    You can define a class as

    // class define in TypeScript
    class VirtualPageTracker extends Tracker {
        private virtualPageName: string = '';
        constructor(name) {
            super(name);
        }
    
        getName(): void {
            return this.virtualPageName;
        }
    
        static getTrackerName(): string {
            return  'VirtualPageTracker';
        }
    }
    

    TypeScript compiler will transcompile it to

    var __extends = (this && this.__extends) || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d = b;
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
    // class define in TypeScript
    var VirtualPageTracker = (function (_super) {
        __extends(VirtualPageTracker, _super);
        function VirtualPageTracker(name) {
            _super.call(this, name);
            this.virtualPageName = '';
        }
        VirtualPageTracker.prototype.getName = function () {
            return this.virtualPageName;
        };
        VirtualPageTracker.getTrackerName = function () {
            return 'VirtualPageTracker';
        };
        return VirtualPageTracker;
    })(Tracker);
    

    Static Type-checking

    TypeScript compiler will check the type (to surface more typing errors at compiling time)

    var name: string;
    name = 2; // type error, assign a number to a string type variable
    
    function foo(value: number) {}
    foo(''); // type error, use a number as a string type parameter
    
    interface Bar {
        setName: (name: string) => void;
        getName: () => string;
    }
    
    
    var bar: Bar = {
        getName: function() {
            return 'myName';
        }
    } // type error, setName function is missing in the object assigned to bar.
    

    A practical example is if we use the wrong data type in the browser beacon, we now get compiling errors. Before migrating to Typescript, they could only be found by testing against the back-end.

    ECMAScript 6 Feature Support

    It is the current version of the ECMAScript Language Specification with more language features.
    With TypeScript, you can start using many ES6 features although it may not be supported in your target browser. TypeScript compile can compile the ts files into “ES3”, “ES5” or “ES6”.

    Some of the features are very handy like:

    // for..of loops
    var arr = ['a', 'b', 'c'];
    for (let item of arr) {
        console.log(item);
    }
    

    It’s compiled to

    // for..of loops
    var arr = ['a', 'b', 'c'];
    for (var _i = 0; _i < arr.length; _i++) {
        var item = arr[_i];
        console.log(item);
    }
    

    Refer to TypeScript ES6 Compatibility Table for more ES6 features you can use.

    Clear API Definition

    To let other TypeScript libraries use your library, you need to create a .d.ts file to declare all your public types and APIs of your library.
    These definition files turned out to be clear and accurate references of your public APIs since they are always maintained and update-to-date because
    you always need them if you write your tests in TypeScript too.

    Refer to https://github.com/borisyankov/DefinitelyTyped for TypeScript definition files created for large amounts of JavaScript libraries.

    Build-in Support for JavaScript Packaging

    You can define one main entry ts file and refer all the ts files you need in the output js file.

    Compiling the main entry ts file with the –out option, the compiler will concatenate all the directly or indirectly referred ts files into one js file in the order they are referred.

    Thus, we can easily tailor our library into multiple versions.
    For example, with the same code base, we are able to generate specific versions of browser agents for desktop and mobile respectively.
    We just need to create one entry file for each version with different ts files referred in it.

    Syntax Similarity to Our Backend Languages (Java, Scala)

    We use Java and Scala at the back-end.
    TypeScript’s similarity to these languages allows our developers can switch between front-end and back-end programming more smoothly.
    Refer http://www.slideshare.net/razvanc/quick-typescript-vs-scala-sample for a quick syntax comparison between TypeScript and Scala.

    Superset of JavaScript

    As a superset of JavaScript, TypeScript has a smooth learning curve for JavaScript developers.
    This means  you can adopt TypeScript in your existing JavaScript projects quickly in an less disruptive way than CoffeeScript or ClojureScript.

    One Missing Feature Suggested

    In addition to the benefit, we also found some missing features could be implemented.
    One of them is to merge the same module into the same function rather than multiple functions.

    module A {
        function foo() { }
    }
    
    module A {
        function bar() {
            foo();
        }
    }
    

    generates below code with compiling error “cannot find name ‘foo’”.

    var A;
    (function(A) {
        function foo() {}
    })(A || (A = {}));
    var A;
    (function(A) {
        function bar() {
            foo();
        }
    })(A || (A = {}));
    

    foo function defined within the first anonymous function call for module A is not visible in the second anonymous function call, so you have to export it as:

    module A {
        export function foo() {}
    }
    
    module A {
        function bar() {
            foo();
        }
    }
    

    generates below code without error:

    var A;
    (function(A) {
        function foo() {}
        A.foo = foo;
    })(A || (A = {}));
    var A;
    (function(A) {
        function bar() {
            A.foo();
        }
    })(A || (A = {}));
    

    The problem here is now A.foo is not only visible to module A. Anyone can call it and modify it now.

    There is no module level visible concept which should be similar to Java’s “package-private” when there is no modifier for Java classes or members.

    This could be solved by generating:

    module A {
        export function foo() {}
    }
    
    module A {
        function bar() {
            foo();
        }
    }
    

    to

    var A;
    (function (A) {
        function foo() { }
        A.foo = foo;
    })(A || (A = {}));
    var A;
    (function (A) {
        function bar() {
            A.foo();
        }
    })(A || (A = {}));
    

    The problem of merging into one function is a potential name conflict between the same module in two files. But the compiler can report error in this case, and if two people are working independently on the same module in two files, it would be better to create two different sub modules. Merging into one function could be a feasible way support module level visibility.

    Answered on April 29, 2021.
    Add Comment
  • Your Answer

    By posting your answer, you agree to the privacy policy and terms of service.