Blog-Archiv

Sonntag, 25. März 2018

A TypeScript Test Installation

Any JavaScript (JS) developer that is tired of fixing bugs that arose from silly programming mistakes sooner or later will switch to a typed programming language. The new ES6 language doesn't yet provide static type checking, although everything is ready for it. Besides the JS alternatives Dart (Google), Elm, and CoffeeScript, there is also TypeScript (TS). Originally started by Microsoft in 2012, it was also promoted and updated by Google's Angular development team since 2016. TypeScript is a super-set of JS, i.e. every JS code is valid TS, but not any TS code is valid JS. Surprisingly TypeScript is much more similar to Java than JS is.

Target of this Blog is to install TypeScript and write a HTML page that uses it, proving that both dependency management and type checks work.

Installing TypeScript

The TypeScript quick-start tells me that there are two ways to install the TS compiler (tsc):

  1. via nodejs package manager npm
  2. via VisualStudio Code IDE

No way to get it without surrounding tools? I decide for the lightweight nodejs variant.

NodeJs

NodeJs makes JavaScript available as "standalone" programming language. JS originally was made for browsers only, accessing the HTML DOM (document object model) and BOM (browser object model), not files, not input- output-streams, not network sockets (except AJAX). Having such functionality in a browser would open your computer completely to the Internet! The only thing a web-page is allowed to store on the browsing computer are cookies, and, since HTML-5, name/value pairs in a local storage.

On server side it absolutely makes sense to access files and other computer resources. NodesJs was started as server-side JS. You can use it also as web server for testing. Mind that when you run a JS interpreter standalone, without a browser as environment, global variables like document or window will be missing. Thus not any script that can run in nodejs can run in a browser, and not any script that can run in a browser can run in nodejs.

But this Blog is not about nodejs, I need it just to install TypeScript.

I'm on my Ubuntu LINUX machine in a command-line terminal window, and I follow the according nodejs instructions, using the native package manager apt. I have curl ("See URL") already installed (do it via apt-get install curl when not):

  curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
  # Make the NodeSource download-repository available for the operating system.
  # Reads a script from the web and executes it as superuser. Yes, this is dangerous.

  sudo apt-get install -y nodejs
  # Actually installs nodejs from that repository.
  # -y: Assume "yes" as answer to all prompts and run non-interactively.

So let's see what we have after installing:

  nodejs --help
  # Her majesty the JavaScript interpreter itself
  # 'node' is a deprecated alias for nodejs

  npm ls
  # Lists all installed nodejs modules.
  # npm spells "nodejs package manager". 
  # It can download and upload libraries, and manage dependencies.

Remember that JS has no built-in dependency management, no include, no import, dependency was expected to be done by the order of HTML <script> elements. This was one of the biggest flaws, and was fixed just recently by ES6. Mind that plain old JS still doesn't support the ES6 import statement, and old browsers may still not support ES6.

TypeScript via npm

In my terminal window, I enter just a single line to install the TypeScript compiler:

  sudo npm install -g typescript
  # -g means "global", install to machine, not to current working directory.

  tsc --version
  # The TypeScript compiler is installed now and globally available.

TypeScript source files traditionally have the .ts extension. Let's try out if it works:

  echo "console.log('Hello World')" >hello-world.ts
  # Write some test source into a TypeScript file

  tsc hello-world.ts
  # Compiles it to hello-world.js

  nodejs hello-world.js
  # Executes hello-world.js, will output >Hello World<

So nodejs at least supports the global console object. Now let's try out a real web page that imports JS compiled from TS.

Dependency Management Test

TypeScript as language implements the ES6 specification concerning dependency management. Most browsers already support it.

For this test I will stick to ES6 import statements, because in future browsers will do dependency resolution. Let's see if TS can handle it, and still provides type-checks for imported functionality. I need an HTML page, there I will refer to an external JS file which was compiled from a TS file.

TS

A basic module hello.ts is responsible for saying "Hello". Use a plain text editor to paste following into a hello.ts file in current working directory:

hello.ts
1
2
3
export function sayHello(name: string) {
    return "Hello "+name;
}

To test dependency management, the page-module index.ts imports hello.ts:

index.ts
1
2
3
4
5
6
7
8
import { sayHello } from "./hello.js";

function displayHello(elementId: string, displayText: string) {
    const element = document.getElementById(elementId);
    element.innerHTML = sayHello(displayText);
}

displayHello("hello", "TypeScript");

HTML

Now I integrate the TS compile-result index.js into a test page index.html:

index.html
<!DOCTYPE html>
<html>
    <body>
        <p id="hello">Loading ...</p>

        <script type="module" src="index.js"></script>
    </body>
</html>

Compile and Test

In command-line terminal, compile the TS sources:

  tsc -t ES6 *.ts
  # "-t ES6" tells tsc that the type of sources is ES6. 

When you load the index.html page into your browser, you should see following now instead of "Loading ...":

Mind that this will work only with browsers that already support ES6 modules! When you look at index.js, which is the compile result of index.ts, you see that the tsc compiler simply left the import statement as it was.

Import Type Check

To try out whether TypeScript also follows the import and can detect type errors there, I create a type mistake in hello.js.

hello.ts
export function sayHello(name: number) {
    return "Hello "+name;
}

As you see, I changed the type of the name parameter from string to number. I would expect that the tsc compilation fails now.

  tsc -t ES6 *.ts

Positive! Output is:

  index.ts(5,34): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Conclusion

The shown TypeScript test environment can be built also on WINDOWS and APPLE operating systems. Of course there are lots of tools that automatically compile sources, e.g. tsc -w will watch all given files and re-compile them as soon as they change. The nodejs world is big, and there are tools for everything that eases your life as a TS developer :-)




Keine Kommentare: