Agenda

  1. Javascript and Types
  2. Typescript and Types
  3. Typescript features
  4. Typescript?

Is Javascript UnTyped?

JavaScript data types

JavaScript is a loosely typed or a dynamic language. That means you don't have to declare the type of a variable ahead of time. The type will get determined automatically while the program is being processed. That also means that you can have the same variable as different types:


                    var foo = 42;    // foo is now a Number
                    var foo = 'bar'; // foo is now a String
                    var foo = true;  // foo is now a Boolean
                

Data types

The latest ECMAScript standard defines seven data types:

Six data types that are primitives: immutable values

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (new in ECMAScript 6)

And

Object

Conclusion

The term Untyped Language is not equivalent to weak typing or to dynamic typing. It implies a language in which values are simply chunks of bits, such as low-level assembler languages.
Javacsript is dynamically typed.

So Javascript has Types...

Typescript

  • Developed by Microsoft (open source)
  • Built on npm
  • Compiled and transpiled to Js with required version
  • Heavily used in Angular2
  • Constantly updated (2.2)

Valid JavaScript is also valid TypeScript!!

So if javascript is typed typescript obviously is.

But Is Typescript Static or dynamic?

Like Daaaa...

Static typing, Type annotations

type is associated with variable or textual expression, and checked at compile-time.


                    function g( a : number ) : number{
                        return a / 10;
                    }
                

Type inference

“Types can be determined from the context, making type annotations optional.

                function g( a ) {
                    return a / 10;
                }
                

What? But… It looks just the same as dynamic one!

Yeah, it does. :) There are programming languages like Haskell that guarantee that types will be extracted from the context and statically checked. Which means that…

You can write the whole program without a single type annotation, and it will be a statically typed program.

“a” is not a number, but it’s inferred as any?

No, it’s not because TypeScript’s type inference is incapable.

It prefers ‘any’ type to ‘number’, thus it’s dynamic by default as regular JavaScript is.

When you want it to be stricter, you have to add type annotation. Not vice versa.

This mix of the type annotations with “any” type is called Gradual typing. When it prefers “any” by default, it’s called “Soft type system”. Not exactly an opposite to dynamic, nor to static typing, but taking the best of both.

No Implicit Any Option


                    {
                        "compilerOptions": {
                            "module": "system",
                            "noImplicitAny": true,  // <----
                            "removeComments": true,
                            "preserveConstEnums": true,
                            "outFile": "../../built/local/tsc.js",
                            "sourceMap": true
                        },
                        "include": [
                            "src/**/*"
                        ],
                        "exclude": [
                            "node_modules",
                            "**/*.spec.ts"
                        ]
                    }
                
This is boooring...
Show me the code

Typescript features


                const num: number =1;
                const str: string = 'Hello';
                const bool: boolean = true;
                const mixed1: string|number = 2;
                const mixed2: string|number = 'World'
            

                //Array
                 const arr:string[] = ['Hello', 'World'];
                 //Tuple
                 const tuple:[string,number] = ['Hello', 1];
                 //Enums
                 enum Color: {Black,White};
                 enum Company: {Other = 0, DV =100};
            

                //Type
                 type status = 'Success'|'Error';
                 //Function
                 const foo: Function;
                 const goo: (x:string) => boolean;
                 public dict :{[key:string]:number} = {key1 :1, key2 :2};
            

Duck Typing

"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck." James Whitcomb Riley

                    interface Duck{
                        walk:()=> void;
                        swim : () => void;
                        quack : () => void;
                    }
                

                    let ProbablyADuck = {
                        walk : () => console.log('walking like a duck');
                        swim : () => console.log('swimming like a duck');
                        quack : () => console.log('quacking like a duck');
                    };

                    function FlyOverWater(bird : Duck){}
                    FlyOverWater(ProbablyADuck); //works!!!
                

Generics


                interface ShelfItem{
                title:string;
                }
                class Shelf<T extends ShelfItem>{
                    private _items :  Array<T = new Array<T();
                    add(item:T):void{
                        this._items.push(item);
                    }
                    getFirst():T{
                        return this._items[0];
                    }
                    find(title:string){
                        return this._items.filter(item => item.title === title)[0];
                    }
                    printTitles():void{
                        this._items.forEach(item => console.log(item.title);)
                    }
                }
                let bookShelf: Shelf<Book = new Shelf<Book();
                let magazineShelf: Shelf<Magazine = new Shelf<Magazine();
            

Function Overloading


                function getTask(taskName:string, deps:string[]) : ITaskGroup;
                function getTask(taskName:string, fn:Function) : ITask;
                function getTask(taskName:string, x:any) : any {
                    if(typeof x === 'function'){
                        return {
                            taskName,
                            fn:x
                        };
                    }
                    if(Array.isArray(x)){
                        return {
                            taskName,
                            deps:x
                    };
                }

            

ES6 features

Destructuring


                    var obj = {a: 10, b: 20};
                    var a = obj.a;
                    var b = obj.b;
                    return a + b;
                

                    const obj = {a: 10, b: 20};
                    const {a, b} = obj;
                    return a + b;
                

Arrow Function


                    function run (){
                        this.count = 0;
                        setInterval(function(){
                            this.count++;
                        }, 1000);
                    }
                

                    function run (){
                        this.count = 0;
                        setInterval(() => {
                            this.count++;
                        }, 1000);
                    }
                

Template Strings


        const prefix = 'https';
        const url = (domain, path, name) =>
                        `${prefix}://${domain}/${path}?name=${'user_' + name}`
        console.log(url('dv.com', 'register', 'miri'))
        // https://dv.com/register?name=user_miri
                

External Typing

TypeScript compiler comes with external declarations for core and DOM libraries (lib.d.ts)

EXCERPT FROM LIB.D.TS #1


                    declare function parseFloat(string: string): number;

                    interface Function {
                        apply(thisArg: any, ...argArray: any[]): any;
                        call(thisArg: any, ...argArray: any[]): any;
                        bind(thisArg: any, ...argArray: any[]): Function;
                        prototype: any;
                        length: number;
                    }
                

EXCERPT FROM LIB.D.TS #2


                    interface Node extends EventTarget {
                        nodeType: number;
                        previousSibling: Node;
                        localName: string;
                        parentNode: Node;
                        nextSibling: Node;
                        // ...
                    }
                

Existing JavaScript libraries

EXCERPT FROM lodash/index.d.ts


                    findLast<T>(
                        collection: T[],
                        callback: ListIterator<T, boolean>,
                        fromIndex?: number
                    ): T|undefined;
                

Typescript?

  • Adds a compile step: longer to load and a lot of setup
  • Code is pretty readable but still not the source code
  • Adding Types take time and design and are not always clear in advance.
  • May cause over engineering.

So do we really need Types?

They don't make QA or testing redundant.
Couldn't we just really on good documentation and design?

“I always make beautiful docs, and I always keep them in sync!“

Humans are so unreliable…
How could you really guarantee that your docs actually conforms to the code?

  • Are you always in the mood?
  • Do you always have time and no excuses?
  • Don’t you make any mistakes?
  • Are you working on it alone, or there’s a whole team of superheroes in charge?

Type annotations is the documentation which is checked by compiler against itself and the code.

it’s guaranteed to be correct and up-to date.

The type system is like training wheels. It keeps you from falling, at the price of slowing you down and limiting flexibility.

Thank you!

Resources: