-
Notifications
You must be signed in to change notification settings - Fork 176
TypeScript Background Information
Doppio is written in TypeScript, which is like JavaScript but with type annotations. Type annotations describe the types of function arguments, return values, and variables. TypeScript uses these annotations to check that your program is not doing anything illegal.
This page will introduce you to TypeScript, and how it is subtly different from JavaScript.
Install NodeJS, and then install TypeScript from the command line:
npm install -g typescript
Open up your favorite text editor, and type in the following:
console.log("Hello World!");
Save the file as hello.ts
, and compile it to JavaScript:
$ tsc hello.ts
tsc
, the TypeScript Compiler, will compile the TypeScript file into JavaScript (hello.js
). Now you can run the JavaScript file in Node:
$ node hello.js
Hello World!
If you look at hello.js
, you'll notice it's identical to hello.ts
! That's because TypeScript is nearly identical to JavaScript, except with type annotations, which we will discuss next.
TypeScript uses type annotations to verify that your program isn't doing anything illegal. Let's walk through a simple example.
In JavaScript, we can write the following function to add two numbers:
function add(num1, num2) {
return num1 + num2;
}
add(5, 4); // Returns 9
However, JavaScript does not prevent you from calling add
with non-numbers, which can result in unpredictable results:
add("hey", [1, 2, 4]); // Returns 'hey1,2,4'
TypeScript lets you declare that add
takes in two numbers as arguments, and returns a number. If you do something illegal, it will warn you when you try to compile your program to JavaScript:
function add(num1: number, num2: number): number {
return num1 + num2;
}
add(5, 4); // Returns 9.
add("hey", [1, 2, 4]); // Those aren't numbers!
If you put the above example into a file named example.ts
and compile it, you'll get an error:
$ tsc example.ts
example.ts(6,5): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
These error messages prevent you from writing incorrect JavaScript programs, and save you a lot of debugging time.
TypeScript lets you define classes, much like other programming languages like Java or C#. JavaScript itself is getting classes in the next version of JavaScript, and TypeScript classes aim to mirror JavaScript classes in syntax and function.
Let's walk through a simple example.
class Animal {
private numberOfLegs: number;
constructor(numberOfLegs: number) {
this.numberOfLegs = numberOfLegs;
}
public getNumberOfLegs(): number { return this.numberOfLegs; }
public makeNoise(): string { return "Silence"; }
}
class Dog extends Animal {
constructor() {
super(4); // Dogs have 4 legs.
}
public makeNoise(): string { return "Woof!"; }
}
function printInfo(animal: Animal) {
console.log(animal.makeNoise());
console.log("Number of legs: " + animal.getNumberOfLegs());
}
var myDog = new Dog();
var myAnimal = new Animal(22);
printInfo(myDog); // "Woof!" "Number of legs: 4"
printInfo(myAnimal); // "Silence" "Number of legs: 22"
Like in Java, classes can also have static fields and methods, but to keep this introduction brief we won't discuss them here.
TypeScript also has interfaces, which describes functions and properties on objects:
interface IAnimal {
makeNoise(): string;
getNumberOfLegs(): number;
}
// From our previous example, Dogs are IAnimals.
var iAnimalInstance: IAnimal = new Dog();
// We can construct an IAnimal out of nothing. These are called object literals in JavaScript.
var iAnimalLiteral: IAnimal = {
makeNoise: function() { return "Moo!"; },
getNumberOfLegs: function() { return 4; }
};
Note that we aren't explicitly declaring the return type of makeNoise
and getNumberOfLegs
on iAnimalLiteral
. TypeScript performs type inference, which means it uses the program's source code to automatically determine (infer) type annotations. For example, it sees that makeNoise
returns "Moo!", so it infers a return type of string!
However, type inference is not always correct. It is generally good programming practice to add explicit annotations to most of your code.
TypeScript has lambdas, which are short one-statement functions that it uses for the function's return value:
// Prints "[ 5, 6, 8 ]"
console.log([1, 2, 4, "foo"].filter((item: any) => typeof item === "number").map((item: number) => item + 4));
TypeScript has template strings, which make it easy to construct print statements:
// A backtick (`) indicates the start and end of a template string. ${} encloses TypeScript code,
// which is evaluated and injected into the string.
console.log(`The current time is ${new Date()}.`);
// Prints "The current time is Thu Mar 05 2015 14:41:29 GMT-0500 (EST)."
And so much more!