### TypeScript
### Angular 2 is built in TypeScript
Angular 2 is built in a Javascript-like language called [TypeScript](http://www.typescriptlang.org/).
You might be skeptical of using a new language just for Angular, but it turns out, there are a lot of great reasons to use TypeScript instead of plain Javascript.
TypeScript isn’t a completely new language, it’s a superset of ES6. If we write ES6 code, it’s perfectly valid and compilable TypeScript code. Here’s a diagram that shows the relationship between the languages:
![ES5, ES6, and TypeScript](https://box.kancloud.cn/2015-07-14_55a489f521975.png)
ES5, ES6, and TypeScript
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f53fdda.png" alt="information" width="50"/></td> <td> <p><strong>What is ES5? What is ES6</strong>? ES5 is short for “ECMAScript 5”, otherwise known as “regular Javascript”. ES5 is the normal Javascript we all know an love. It runs in more-or-less every browser. ES6 is the next version of Javascript, which we talk more about below.</p> </td> </tr></tbody></table>
At the publishing of this book, very few browsers will run ES6 out of the box, much less TypeScript. To solve this issue we have _transpilers_ (or sometimes called _transcompiler_). The TypeScript transpiler takes our TypeScript code as input and outputs ES5 code that nearly all browsers understand.
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f548ffd.png" alt="information" width="50"/></td> <td> <p>For converting TypeScript to ES5 there is a single transpiler written by the core TypeScript team. However if we wanted to convert <em>ES6</em> code (not TypeScript) to <em>ES5</em> there are two major ES6-to-ES5 transpilers: <strong><a href="https://github.com/google/traceur-compiler">traceur</a></strong> by Google and <strong><a href="https://babeljs.io/">babel</a></strong> created by the JavaScript community. We’re not going to be using either directly for this book, but they’re both great projects that are worth knowing about.</p> <p>We installed TypeScript in the last chapter, but in case you’re just starting out in this chapter, you can install it like so:</p> <p><code>npm install -g 'typescript@^1.5.0-beta'</code></p> </td> </tr></tbody></table>
TypeScript is an official collaboration between Microsoft and Google. That’s great news because with two tech heavyweights behind it we know that it will be supported for a long time. Both groups are committed to moving the web forward and as developers we win because of it.
One of the great things about transpilers is that they allow relatively small teams to make improvements to a language without requiring everyone on the internet upgrade their browser.
One thing to point out: we don’t _have_ to use TypeScript with Angular2. If you want to use ES5 (i.e. “regular” JavaScript), you definitely can. There is an ES5 API that provides access to all functionality of Angular2. Then why should we use TypeScript at all? Because there are some great features in TypeScript that make development a lot better.
### What do we get with TypeScript?
There are five big improvements that TypeScript bring over ES5:
- types
- classes
- annotations
- imports
- language utilities (e.g. destructuring)
Let’s deal with these one at a time.
### Types
The major improvement of TypeScript over ES6, that gives the language its name, is the typing system.
For some people the lack of type checking is considered one of the benefits of using a language like JavaScript. You might be a little skeptical of type checking but I’d encourage you to give it a chance. One of the great things about type checking is that
1. it helps when _writing_ code because it can prevent bugs at compile time and
1. it helps when _reading_ code because if gives a clarifies your intentions
It’s also worth noting that types are optional in TypeScript. If we want to write some quick code or prototype a feature, we can omit types and gradually add them as the code becomes more mature.
TypeScript’s basic types are the same ones we’ve been using implicitly when we write “normal” JavaScript code: strings, numbers, booleans, etc.
Up until ES5, we would define variables with the `var` keyword, like `var name;`.
The new TypeScript syntax is a natural evolution from ES5, we still use `var` but now we can optionally provide the variable type along with it’s name:
~~~
1
~~~
~~~
var
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
;
~~~
When declaring functions we can use types for arguments and return values:
~~~
1
~~~
~~~
function
~~~
~~~
greetText
~~~
~~~
(
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
)
~~~
~~~
:
~~~
~~~
string
~~~
~~~
{
~~~
~~~
2
~~~
~~~
return
~~~
~~~
"Hello "
~~~
~~~
+
~~~
~~~
name
~~~
~~~
;
~~~
~~~
3
~~~
~~~
}
~~~
In the example above we are defining a new function called `greetText` which takes one argument: `name`. The syntax `name: string` says that this function expects `name` to be a `string`. Our code won’t compile if we call this function with anything other than a `string` and that’s a good thing because otherwise we’d introduce a bug.
Notice that the `greetText` function also has a new syntax after the parentheses: `: string {`. The colon indicates that we will specify the return type for this function, which in this case is a `string`. This is helpful because 1. if we accidentally return anything other than a `string` in our code, the compiler will tell us that we made a mistake and 2. any other developers who want to use this function know precisely what type of object they’ll be getting.
Let’s see what happens if we try to write code that doesn’t conform to our declared typing:
~~~
1
~~~
~~~
function
~~~
~~~
hello
~~~
~~~
(
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
)
~~~
~~~
:
~~~
~~~
string
~~~
~~~
{
~~~
~~~
2
~~~
~~~
return
~~~
~~~
12
~~~
~~~
;
~~~
~~~
3
~~~
~~~
}
~~~
If we try to compile it, we’ll see the following error:
~~~
1
~~~
~~~
$
~~~
tsc compile-error.ts
~~~
2
~~~
compile-error.ts
~~~
(
~~~
2,12
~~~
)
~~~
: error TS2322: Type
~~~
'number'
~~~
is not assignable to
~~~
type
~~~
~~~
's\
~~~
~~~
3
~~~
~~~
tring'
~~~
.
What happened here? We tried to return `12` which is a `number`, but we stated that `hello` would return a `string` (by putting the `): string {` after the argument declaration).
In order to correct this, we need to update the function declaration to return a `number`:
~~~
1
~~~
~~~
function
~~~
~~~
hello
~~~
~~~
(
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
)
~~~
~~~
:
~~~
~~~
number
~~~
~~~
{
~~~
~~~
2
~~~
~~~
return
~~~
~~~
12
~~~
~~~
;
~~~
~~~
3
~~~
~~~
}
~~~
This is one small example, but already we can see that by using types it can save us from a lot of bugs down the road.
So now that we know how to use types, how can we know what types are available to use? Let’s look at the list of built-in types, and then we’ll figure out how to create our own.
#### Trying it out with a REPL
To play with the examples on this chapter, let’s install a nice little utility called [**TSUN**](https://github.com/HerringtonDarkholme/typescript-repl) (TypeScript Upgraded Node):
~~~
1
~~~
~~~
$
~~~
npm install -g tsun
Now start tsun:
~~~
1
~~~
~~~
$
~~~
tsun
~~~
2
~~~
TSUN : TypeScript Upgraded Node
~~~
3
~~~
~~~
type
~~~
in TypeScript expression to evaluate
~~~
4
~~~
~~~
type
~~~
:help
~~~
for
~~~
commands in repl
~~~
5
~~~
~~~
6
~~~
>
That little `>` is the prompt indicating that TSUN is ready to take in commands.
In most of the examples below, you can copy and paste into this terminal and play long.
### Built-in types
##### String
A string holds text and is declared using the `string` type:
~~~
1
~~~
~~~
var
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
=
~~~
~~~
'
~~~
~~~
Felipe
~~~
~~~
'
~~~
~~~
;
~~~
##### Number
A number is any type of numeric value. In TypeScript, all numbers are represented as floating point. The type for numbers is `number`:
~~~
1
~~~
~~~
var
~~~
~~~
age
~~~
~~~
:
~~~
~~~
integer
~~~
~~~
=
~~~
~~~
36
~~~
~~~
;
~~~
##### Boolean
The `boolean` holds either `true` or `false` as the value.
~~~
1
~~~
~~~
var
~~~
~~~
married
~~~
~~~
:
~~~
~~~
boolean
~~~
~~~
=
~~~
~~~
true
~~~
~~~
;
~~~
##### Array
Arrays are declared with the `Array` type. However, because an Array is a collection, we also need to specify the type of the objects _in_ the Array.
We specify the type of the items in the array with either the `Array<type>` or `type[]` notations:
~~~
1
~~~
~~~
var
~~~
~~~
jobs
~~~
~~~
:
~~~
~~~
Array
~~~
~~~
<
~~~
~~~
string
~~~
~~~
>
~~~
~~~
=
~~~
~~~
[
~~~
~~~
'IBM'
~~~
~~~
,
~~~
~~~
'Microsoft'
~~~
~~~
,
~~~
~~~
'Google'
~~~
~~~
]
~~~
;
~~~
2
~~~
var jobs: string
~~~
[]
~~~
=
~~~
[
~~~
~~~
'Apple'
~~~
~~~
,
~~~
~~~
'Dell'
~~~
~~~
,
~~~
~~~
'HP'
~~~
~~~
]
~~~
;
Or similarly with a `number`:
~~~
1
~~~
~~~
var
~~~
~~~
jobs
~~~
~~~
:
~~~
~~~
Array
~~~
~~~
<
~~~
~~~
number
~~~
~~~
>
~~~
~~~
=
~~~
~~~
[
~~~
~~~
1
~~~
~~~
,
~~~
~~~
2
~~~
~~~
,
~~~
~~~
3
~~~
~~~
]
~~~
;
~~~
2
~~~
var jobs: number
~~~
[]
~~~
=
~~~
[
~~~
~~~
4
~~~
~~~
,
~~~
~~~
5
~~~
~~~
,
~~~
~~~
6
~~~
~~~
]
~~~
;
##### Enums
Enums work by naming numeric values. For instance, if we wanted to have a fixed list of roles a person may have we could write this:
~~~
1
~~~
~~~
enum
~~~
~~~
Role
~~~
~~~
{
~~~
~~~
Employee
~~~
~~~
,
~~~
~~~
Manager
~~~
~~~
,
~~~
~~~
Admin
~~~
~~~
};
~~~
~~~
2
~~~
~~~
var
~~~
~~~
role
~~~
~~~
:
~~~
~~~
Role
~~~
~~~
=
~~~
~~~
Role
~~~
~~~
.
~~~
~~~
Employee
~~~
~~~
;
~~~
The default initial value for an enum is 0. You can tweak either the start of the range:
~~~
1
~~~
~~~
enum
~~~
~~~
Role
~~~
~~~
{
~~~
~~~
Employee
~~~
~~~
=
~~~
~~~
3
~~~
~~~
,
~~~
~~~
Manager
~~~
~~~
,
~~~
~~~
Admin
~~~
~~~
};
~~~
~~~
2
~~~
~~~
var
~~~
~~~
role
~~~
~~~
:
~~~
~~~
Role
~~~
~~~
=
~~~
~~~
Role
~~~
~~~
.
~~~
~~~
Employee
~~~
~~~
;
~~~
In a way that `Employee` is `3`, `Manager` is `4` and Admin is `5`, and we can even set individual values:
~~~
1
~~~
~~~
enum
~~~
~~~
Role
~~~
~~~
{
~~~
~~~
Employee
~~~
~~~
=
~~~
~~~
3
~~~
~~~
,
~~~
~~~
Manager
~~~
~~~
=
~~~
~~~
5
~~~
~~~
,
~~~
~~~
Admin
~~~
~~~
=
~~~
~~~
7
~~~
~~~
};
~~~
~~~
2
~~~
~~~
var
~~~
~~~
role
~~~
~~~
:
~~~
~~~
Role
~~~
~~~
=
~~~
~~~
Role
~~~
~~~
.
~~~
~~~
Employee
~~~
~~~
;
~~~
You can also look up the name of a given enum, but using its value:
~~~
1
~~~
~~~
enum
~~~
~~~
Role
~~~
~~~
{
~~~
~~~
Employee
~~~
~~~
,
~~~
~~~
Manager
~~~
~~~
,
~~~
~~~
Admin
~~~
~~~
};
~~~
~~~
2
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
'
~~~
~~~
Roles
~~~
~~~
:
~~~
~~~
'
~~~
~~~
,
~~~
~~~
Role
~~~
~~~
[
~~~
~~~
0
~~~
~~~
],
~~~
~~~
','
~~~
~~~
,
~~~
~~~
Role
~~~
~~~
[
~~~
~~~
1
~~~
~~~
],
~~~
~~~
'
~~~
~~~
and
~~~
~~~
'
~~~
~~~
,
~~~
~~~
Role
~~~
~~~
[
~~~
~~~
2
~~~
~~~
]);
~~~
##### Any
`any` is the default type if we omit typing for a given variable. Having a variable of type `any` allows it to receive any kind of value:
~~~
1
~~~
~~~
var
~~~
~~~
something
~~~
~~~
:
~~~
~~~
any
~~~
~~~
=
~~~
~~~
'
~~~
~~~
as
~~~
~~~
string
~~~
~~~
'
~~~
~~~
;
~~~
~~~
2
~~~
~~~
something
~~~
~~~
=
~~~
~~~
1
~~~
~~~
;
~~~
~~~
3
~~~
~~~
something
~~~
~~~
=
~~~
~~~
[
~~~
~~~
1
~~~
~~~
,
~~~
~~~
2
~~~
~~~
,
~~~
~~~
3
~~~
~~~
];
~~~
##### Void
Using `void` means there’s no type expected. This is usually in functions with no return value:
~~~
1
~~~
~~~
function
~~~
~~~
setName
~~~
~~~
(
~~~
~~~
name
~~~
~~~
:
~~~
~~~
string
~~~
~~~
)
~~~
~~~
:
~~~
~~~
void
~~~
~~~
{
~~~
~~~
2
~~~
~~~
this
~~~
~~~
.
~~~
~~~
name
~~~
~~~
=
~~~
~~~
name
~~~
~~~
;
~~~
~~~
3
~~~
~~~
}
~~~
### Classes
In Javascript ES5 object oriented programming was accomplished by using prototype-based objects. This model doesn’t use classes, but instead relies on _prototypes_.
A number of good practices have been adopted by the JavaScript community to compensate the lack of classes. A good summary of those good practices can be found in [Mozilla Developer Network’s JavaScript Guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide), and you can find a good overview on the [Introduction to Object-Oriented Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript) page.
However, in ES6 we finally have built-in classes in Javascript.
To define a class we use the new `class` keyword and give our class a name and a body:
~~~
1
~~~
~~~
class
~~~
~~~
Vehicle
~~~
~~~
{
~~~
~~~
2
~~~
~~~
}
~~~
Classes may have _properties_, _methods_, and _constructors_.
#### Properties
Properties define data attached to an instance of a class. For example, a class named `Person` might have properties like `first_name`, `last_name` and `age`.
Each property in a class can optionally have a type. For example, we could say that the `first_name` and `last_name` properties are `string`s and the `age` property is a `number`.
The result declaration for a `Person` class that looks like this:
~~~
1
~~~
~~~
class
~~~
~~~
Person
~~~
~~~
{
~~~
~~~
2
~~~
~~~
first_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
3
~~~
~~~
last_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
4
~~~
~~~
age:
~~~
~~~
number
~~~
~~~
;
~~~
~~~
5
~~~
~~~
}
~~~
#### Methods
Methods are functions that run in context of an object. To call a method on an object, we first have to have an instance of that object.
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f569499.png" alt="information" width="50"/></td> <td> <p>To instantiate a class, we use the <code>new</code> keyword. Use <code>new Person()</code> to create a new instance of the <code>Person</code> class, for example.</p> </td> </tr></tbody></table>
If we wanted to add a way to greet a `Person` using the class above, we would write something like:
~~~
1
~~~
~~~
class
~~~
~~~
Person
~~~
~~~
{
~~~
~~~
2
~~~
~~~
first_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
3
~~~
~~~
last_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
4
~~~
~~~
age:
~~~
~~~
number
~~~
~~~
;
~~~
~~~
5
~~~
~~~
6
~~~
~~~
`greet``()` `{`
~~~
~~~
7
~~~
~~~
`console``.``log``(``"Hello"``,` `this``.``first_name``);`
~~~
~~~
8
~~~
~~~
`}`
~~~
~~~
9
~~~
~~~
}
~~~
Notice that we’re able to access the `first_name` for this `Person` by using the `this` keyword and calling `this.first_name`.
When methods don’t declare an explicit returning type and return a value, it’s assumed they can return anything (`any` type). However, in this case we are returning `void`, since there’s no explicit return statement.
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f5735cc.png" alt="information" width="50"/></td> <td> <p>Note that a <code>void</code> value is also a valid <code>any</code> value.</p> </td> </tr></tbody></table>
In order to invoke the `greet` method, you would need to first have an instance of the `Person` class. Here’s how we do that:
~~~
1
~~~
~~~
// declare a variable of type Person
~~~
~~~
2
~~~
~~~
var
~~~
~~~
p:
~~~
~~~
Person
~~~
~~~
;
~~~
~~~
3
~~~
~~~
4
~~~
~~~
// instantiate a new Person instance
~~~
~~~
5
~~~
~~~
p
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Person
~~~
~~~
();
~~~
~~~
6
~~~
~~~
7
~~~
~~~
// give it a first_name
~~~
~~~
8
~~~
~~~
p
~~~
~~~
.
~~~
~~~
first_name
~~~
~~~
=
~~~
~~~
'
~~~
~~~
Felipe
~~~
~~~
';
~~~
~~~
9
~~~
~~~
10
~~~
~~~
// call the greet method
~~~
~~~
11
~~~
~~~
p
~~~
~~~
.
~~~
~~~
greet
~~~
~~~
();
~~~
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f57d60c.png" alt="information" width="50"/></td> <td> <p>You can declare a variable and instantiate a class on the same line if you want:</p> <div class="code-block"><div class="highlight"><pre><code class="lineno">1</code> <code class="n">var</code> <code class="n">p</code><code class="o">:</code> <code class="n">Person</code> <code class="o">=</code> <code class="n">new</code> <code class="n">Person</code><code class="p">();</code>
</pre></div> </div> </td> </tr></tbody></table>
Say we want to have a method on the `Person` class that returns a value. For instance, to know the age of a `Person` in a number of years from now, we could write:
~~~
1
~~~
~~~
class
~~~
~~~
Person
~~~
~~~
{
~~~
~~~
2
~~~
~~~
first_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
3
~~~
~~~
last_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
4
~~~
~~~
age:
~~~
~~~
number
~~~
~~~
;
~~~
~~~
5
~~~
~~~
6
~~~
~~~
greet
~~~
~~~
()
~~~
~~~
{
~~~
~~~
7
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
"Hello"
~~~
~~~
,
~~~
~~~
this
~~~
~~~
.
~~~
~~~
first_name
~~~
~~~
);
~~~
~~~
8
~~~
~~~
}
~~~
~~~
9
~~~
~~~
10
~~~
~~~
`ageInYears``(``years``:` `number``)``:` `number` `{`
~~~
~~~
11
~~~
~~~
`return` `this``.``age` `+` `years``;`
~~~
~~~
12
~~~
~~~
`}`
~~~
~~~
13
~~~
~~~
}
~~~
~~~
1
~~~
~~~
// instantiate a new Person instance
~~~
~~~
2
~~~
~~~
var
~~~
~~~
p:
~~~
~~~
Person
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Person
~~~
~~~
();
~~~
~~~
3
~~~
~~~
4
~~~
~~~
// set initial age
~~~
~~~
5
~~~
~~~
p
~~~
~~~
.
~~~
~~~
age
~~~
~~~
=
~~~
~~~
6
~~~
~~~
;
~~~
~~~
6
~~~
~~~
7
~~~
~~~
// how old will he be in 12 years?
~~~
~~~
8
~~~
~~~
p
~~~
~~~
.
~~~
~~~
ageInYears
~~~
~~~
(
~~~
~~~
12
~~~
~~~
);
~~~
~~~
9
~~~
~~~
10
~~~
~~~
// -> 18
~~~
#### Constructors
A _constructor_ is a special method that is executed when a new instance of the class is being created. Usually, the constructor is where you perform any initial setup for new objects.
Constructor methods must be named `constructor`. They can optionally take parameters but they can’t return any values, since they are called when the class is being instantiated (i.e. an instance of the class is being created, no other value can be returned).
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f58aaa8.png" alt="information" width="50"/></td> <td> <p>In order to instantiate a class we call the class constructor method by using the class name: <code>new ClassName()</code>.</p> </td> </tr></tbody></table>
When a class has no constructor defined explicitly one will be created automatically:
~~~
1
~~~
~~~
class
~~~
~~~
Vehicle
~~~
~~~
{
~~~
~~~
2
~~~
~~~
}
~~~
~~~
3
~~~
~~~
var
~~~
~~~
v
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Vehicle
~~~
~~~
();
~~~
Is the same as:
~~~
1
~~~
~~~
class
~~~
~~~
Vehicle
~~~
~~~
{
~~~
~~~
2
~~~
~~~
constructor
~~~
~~~
()
~~~
~~~
{
~~~
~~~
3
~~~
~~~
}
~~~
~~~
4
~~~
~~~
}
~~~
~~~
5
~~~
~~~
var
~~~
~~~
v
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Vehicle
~~~
~~~
();
~~~
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f594b8a.png" alt="information" width="50"/></td> <td> <p>In TypeScript you can have only <strong>one constructor per class</strong>.</p> <p>That is a departure from ES6 which allows one class to have more than one constructor as long as they have a different number of parameters.</p> </td> </tr></tbody></table>
Constructors can take parameters when we want to parameterize our new instance creation.
For example, we can change `Person` to have a constructor that initializes our data:
~~~
1
~~~
~~~
class
~~~
~~~
Person
~~~
~~~
{
~~~
~~~
2
~~~
~~~
first_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
3
~~~
~~~
last_name:
~~~
~~~
string
~~~
~~~
;
~~~
~~~
4
~~~
~~~
age:
~~~
~~~
number
~~~
~~~
;
~~~
~~~
5
~~~
~~~
6
~~~
~~~
`constructor``(``first_name``:` `string``,` `last_name``:` `string``,` `age``:` `number``)` `{`
~~~
~~~
7
~~~
~~~
`this``.``first_name` `=` `first_name``;`
~~~
~~~
8
~~~
~~~
`this``.``last_name` `=` `last_name``;`
~~~
~~~
9
~~~
~~~
`this``.``age` `=` `age``;`
~~~
~~~
10
~~~
~~~
`}`
~~~
~~~
11
~~~
~~~
12
~~~
~~~
greet
~~~
~~~
()
~~~
~~~
{
~~~
~~~
13
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
"Hello"
~~~
~~~
,
~~~
~~~
this
~~~
~~~
.
~~~
~~~
first_name
~~~
~~~
);
~~~
~~~
14
~~~
~~~
}
~~~
~~~
15
~~~
~~~
16
~~~
~~~
ageInYears
~~~
~~~
(
~~~
~~~
years
~~~
~~~
:
~~~
~~~
number
~~~
~~~
)
~~~
~~~
:
~~~
~~~
number
~~~
~~~
{
~~~
~~~
17
~~~
~~~
return
~~~
~~~
this
~~~
~~~
.
~~~
~~~
age
~~~
~~~
+
~~~
~~~
years
~~~
~~~
;
~~~
~~~
18
~~~
~~~
}
~~~
~~~
19
~~~
~~~
}
~~~
It makes our previous example a little easier to write:
~~~
1
~~~
~~~
var
~~~
~~~
p
~~~
~~~
:
~~~
~~~
Person
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Person
~~~
~~~
(
~~~
~~~
'
~~~
~~~
Felipe
~~~
~~~
'
~~~
~~~
,
~~~
~~~
'
~~~
~~~
Coury
~~~
~~~
'
~~~
~~~
,
~~~
~~~
36
~~~
~~~
);
~~~
~~~
2
~~~
~~~
p
~~~
~~~
.
~~~
~~~
greet
~~~
~~~
();
~~~
This way the person’s names and age are set for us when the object is created.
#### Inheritance
Another import aspect of object oriented programming is inheritance. Inheritance is a way to indicate that a class receives behavior from a parent class. Then we can override, modify or augment those behaviors on the new class.
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f5a0562.png" alt="information" width="50"/></td> <td> <p>If you want to have a deeper understanding of how inheritance used to work in ES5, take a look at the Mozilla Developer Network article about it: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">Inheritance and the prototype chain</a>.</p> </td> </tr></tbody></table>
TypeScript fully supports inheritance and, unlike ES5, it’s built into the core language. Inheritance is achieved through the `extends` keyword.
To illustrate, let’s say we’ve created a `Report` class:
~~~
1
~~~
~~~
class
~~~
~~~
Report
~~~
~~~
{
~~~
~~~
2
~~~
~~~
data
~~~
~~~
:
~~~
~~~
Array
~~~
~~~
<
~~~
~~~
string
~~~
~~~
>
~~~
~~~
;
~~~
~~~
3
~~~
~~~
4
~~~
~~~
constructor
~~~
~~~
(
~~~
~~~
data
~~~
~~~
:
~~~
~~~
Array
~~~
~~~
<
~~~
~~~
string
~~~
~~~
>
~~~
~~~
)
~~~
~~~
{
~~~
~~~
5
~~~
~~~
this.data
~~~
~~~
=
~~~
~~~
data
~~~
~~~
;
~~~
~~~
6
~~~
~~~
}
~~~
~~~
7
~~~
~~~
8
~~~
~~~
run
~~~
~~~
()
~~~
~~~
{
~~~
~~~
9
~~~
~~~
this.data.forEach
~~~
~~~
(
~~~
~~~
function
~~~
~~~
(
~~~
~~~
line
~~~
~~~
)
~~~
~~~
{
~~~
~~~
console.log
~~~
~~~
(
~~~
~~~
line
~~~
~~~
);
~~~
~~~
});
~~~
~~~
10
~~~
~~~
}
~~~
~~~
11
~~~
~~~
}
~~~
This report has a property `data` which is an `Array` of `string`s. When we call `run` we loop over each element of `data` and print them out using `console.log`
<table class="information sidebarish"><tbody><tr><td class="sidebar-icon"> <img class="sidebar-image" src="https://box.kancloud.cn/2015-07-14_55a489f5e2444.png" alt="information" width="50"/></td> <td> <p><code>.forEach</code> is a method on <code>Array</code> that accepts a function as an argument and calls that function for each element in the <code>Array</code>.</p> </td> </tr></tbody></table>
This `Report` works by adding lines and then calling `run` to print out the lines:
~~~
1
~~~
~~~
var
~~~
~~~
r
~~~
~~~
:
~~~
~~~
Report
~~~
~~~
=
~~~
~~~
new
~~~
~~~
Report
~~~
~~~
([
~~~
~~~
'
~~~
~~~
First
~~~
~~~
line
~~~
~~~
'
~~~
~~~
,
~~~
~~~
'
~~~
~~~
Second
~~~
~~~
line
~~~
~~~
'
~~~
~~~
]);
~~~
~~~
2
~~~
~~~
r
~~~
~~~
.
~~~
~~~
run
~~~
~~~
();
~~~
Running this should show:
~~~
1
~~~
~~~
First
~~~
~~~
line
~~~
~~~
2
~~~
~~~
Second
~~~
~~~
line
~~~
Now let’s say we want to have a second report that takes some headers and some data but we still want to reuse how the `Report` class presents the data to the user.
To reuse that behavior from the `Report` class we can use inheritance with the `extends` keyword:
~~~
1
~~~
~~~
class
~~~
~~~
TabbedReport
~~~
~~~
extends
~~~
~~~
Report
~~~
~~~
{
~~~
~~~
2
~~~
~~~
headers
~~~
~~~
:
~~~
~~~
Array
~~~
~~~
<
~~~
~~~
string
~~~
~~~
>
~~~
~~~
;
~~~
~~~
3
~~~
~~~
4
~~~
~~~
constructor
~~~
~~~
(
~~~
~~~
headers
~~~
~~~
:
~~~
~~~
string
~~~
~~~
[
~~~
~~~
]
~~~
, values: string
~~~
[]
~~~
) {
~~~
5
~~~
this.headers = headers;
~~~
6
~~~
super(values)
~~~
7
~~~
}
~~~
8
~~~
~~~
9
~~~
run() {
~~~
10
~~~
console.log(headers);
~~~
11
~~~
super.run();
~~~
12
~~~
}
~~~
13
~~~
}
~~~
1
~~~
~~~
var
~~~
~~~
headers
~~~
~~~
:
~~~
~~~
string
~~~
~~~
[]
~~~
~~~
=
~~~
~~~
[
~~~
~~~
'
~~~
~~~
Name
~~~
~~~
'
~~~
~~~
];
~~~
~~~
2
~~~
~~~
var
~~~
~~~
data
~~~
~~~
:
~~~
~~~
string
~~~
~~~
[]
~~~
~~~
=
~~~
~~~
[
~~~
~~~
'
~~~
~~~
Alice
~~~
~~~
Green
~~~
~~~
'
~~~
~~~
,
~~~
~~~
'
~~~
~~~
Paul
~~~
~~~
Pfifer
~~~
~~~
'
~~~
~~~
,
~~~
~~~
'
~~~
~~~
Louis
~~~
~~~
Blakenship
~~~
~~~
'
~~~
~~~
];
~~~
~~~
3
~~~
~~~
var
~~~
~~~
r
~~~
~~~
:
~~~
~~~
TabbedReport
~~~
~~~
=
~~~
~~~
new
~~~
~~~
TabbedReport
~~~
~~~
(
~~~
~~~
headers
~~~
~~~
,
~~~
~~~
data
~~~
~~~
)
~~~
~~~
4
~~~
~~~
r
~~~
~~~
.
~~~
~~~
run
~~~
~~~
();
~~~
### Utilities
ES6, and by extension TypeScript provides a number of syntax features that make programming really enjoyable. Two important ones are:
- fat arrow function syntax
- template strings
#### Fat Arrow Functions
Fat arrow `=>` functions are a shorthand notation for writing functions.
In ES5, whenever we want to use a function as an argument we have to use the `function` keyword along with `{}` braces like so:
~~~
1
~~~
~~~
// ES5-like example
~~~
~~~
2
~~~
~~~
var
~~~
~~~
data
~~~
~~~
=
~~~
~~~
['
~~~
~~~
Alice
~~~
~~~
Green
~~~
~~~
',
~~~
~~~
'
~~~
~~~
Paul
~~~
~~~
Pfifer
~~~
~~~
',
~~~
~~~
'
~~~
~~~
Louis
~~~
~~~
Blakenship
~~~
~~~
'];
~~~
~~~
3
~~~
~~~
data
~~~
~~~
.
~~~
~~~
forEach
~~~
~~~
(
~~~
~~~
function
~~~
~~~
(
~~~
~~~
line
~~~
~~~
)
~~~
~~~
{
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
line
~~~
~~~
);
~~~
~~~
});
~~~
However with the `=>` syntax we can instead rewrite it like so:
~~~
1
~~~
~~~
// Typescript example
~~~
~~~
2
~~~
~~~
var
~~~
~~~
data:
~~~
~~~
string
~~~
~~~
[]
~~~
~~~
=
~~~
~~~
['
~~~
~~~
Alice
~~~
~~~
Green
~~~
~~~
',
~~~
~~~
'
~~~
~~~
Paul
~~~
~~~
Pfifer
~~~
~~~
',
~~~
~~~
'
~~~
~~~
Louis
~~~
~~~
Blakenship
~~~
~~~
'];
~~~
~~~
3
~~~
~~~
data
~~~
~~~
.
~~~
~~~
forEach
~~~
~~~
(
~~~
~~~
(
~~~
~~~
line
~~~
~~~
)
~~~
~~~
=>
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
line
~~~
~~~
)
~~~
~~~
);
~~~
The `=>` syntax can be used both as an expression:
~~~
1
~~~
~~~
var
~~~
~~~
evens
~~~
~~~
=
~~~
~~~
[
~~~
~~~
2
~~~
~~~
,
~~~
~~~
4
~~~
~~~
,
~~~
~~~
6
~~~
~~~
,
~~~
~~~
8
~~~
~~~
];
~~~
~~~
2
~~~
~~~
var
~~~
~~~
odds
~~~
~~~
=
~~~
~~~
evens
~~~
~~~
.
~~~
~~~
map
~~~
~~~
(
~~~
~~~
v
~~~
~~~
=>
~~~
~~~
v
~~~
~~~
+
~~~
~~~
1
~~~
~~~
);
~~~
Or as a statement:
~~~
1
~~~
~~~
data
~~~
~~~
.
~~~
~~~
forEach
~~~
~~~
(
~~~
~~~
line
~~~
~~~
=>
~~~
~~~
{
~~~
~~~
2
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
line
~~~
~~~
.
~~~
~~~
toUpperCase
~~~
~~~
())
~~~
~~~
3
~~~
~~~
});
~~~
One important feature of the `=>` syntax is that it shares the same `this` as the surrounding code. This is **important** and different than what happens when you normally create a `function` in Javascript. Generally when you write a `function` in Javascript that function is given it’s own `this`. Sometimes in Javascript we see code like this:
~~~
1
~~~
~~~
var
~~~
~~~
nate
~~~
~~~
=
~~~
~~~
{
~~~
~~~
2
~~~
~~~
name
~~~
~~~
:
~~~
~~~
"Nate"
~~~
~~~
,
~~~
~~~
3
~~~
~~~
guitars
~~~
~~~
:
~~~
~~~
[
~~~
~~~
"Gibson"
~~~
~~~
,
~~~
~~~
"Martin"
~~~
~~~
,
~~~
~~~
"Taylor"
~~~
~~~
]
~~~
~~~
4
~~~
~~~
printGuitars
~~~
~~~
:
~~~
~~~
function
~~~
~~~
()
~~~
~~~
{
~~~
~~~
5
~~~
~~~
var
~~~
~~~
self
~~~
~~~
=
~~~
~~~
this
~~~
~~~
;
~~~
~~~
6
~~~
~~~
this
~~~
~~~
.
~~~
~~~
guitars
~~~
~~~
.
~~~
~~~
forEach
~~~
~~~
(
~~~
~~~
function
~~~
~~~
(
~~~
~~~
g
~~~
~~~
)
~~~
~~~
{
~~~
~~~
7
~~~
~~~
// this.name is undefined so we have to use self.name
~~~
~~~
8
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
self
~~~
~~~
.
~~~
~~~
name
~~~
~~~
+
~~~
~~~
" plays a "
~~~
~~~
+
~~~
~~~
g
~~~
~~~
);
~~~
~~~
9
~~~
~~~
});
~~~
~~~
10
~~~
~~~
}
~~~
~~~
11
~~~
~~~
};
~~~
Because the fat arrow shares `this` with its surrounding code, we can instead write this:
~~~
1
~~~
~~~
var
~~~
~~~
nate
~~~
~~~
=
~~~
~~~
{
~~~
~~~
2
~~~
~~~
name
~~~
~~~
:
~~~
~~~
"Nate"
~~~
~~~
,
~~~
~~~
3
~~~
~~~
guitars
~~~
~~~
:
~~~
~~~
[
~~~
~~~
"Gibson"
~~~
~~~
,
~~~
~~~
"Martin"
~~~
~~~
,
~~~
~~~
"Taylor"
~~~
~~~
]
~~~
~~~
4
~~~
~~~
printGuitars
~~~
~~~
:
~~~
~~~
function
~~~
~~~
()
~~~
~~~
{
~~~
~~~
5
~~~
~~~
this
~~~
~~~
.
~~~
~~~
guitars
~~~
~~~
.
~~~
~~~
forEach
~~~
~~~
(
~~~
~~~
(
~~~
~~~
g
~~~
~~~
)
~~~
~~~
=>
~~~
~~~
{
~~~
~~~
6
~~~
~~~
console
~~~
~~~
.
~~~
~~~
log
~~~
~~~
(
~~~
~~~
this
~~~
~~~
.
~~~
~~~
name
~~~
~~~
+
~~~
~~~
" plays a "
~~~
~~~
+
~~~
~~~
g
~~~
~~~
);
~~~
~~~
7
~~~
~~~
});
~~~
~~~
8
~~~
~~~
}
~~~
~~~
9
~~~
~~~
};
~~~
Arrows are a great way to cleanup your inline functions. It makes it even easier to use higher-order functions in Javascript.
#### Template Strings
In ES6 new template strings were introduced. The two great features of template strings are
1. Variables within strings (without being forced to concatenate with `+`) and
1. Multi-line strings
##### Variables in strings
This feature is also called “string interpolation.” The idea is that you can put variables right in your strings. Here’s how:
~~~
1
~~~
var firstName = "Nate";
~~~
2
~~~
var lastName = "Murray";
~~~
3
~~~
~~~
4
~~~
// interpolate a string
~~~
5
~~~
var greeting = `Hello
~~~
${
~~~
~~~
firstName
~~~
~~~
}
~~~
~~~
${
~~~
~~~
lastName
~~~
~~~
}
~~~
`;
~~~
6
~~~
~~~
7
~~~
console.log(greeting);
Note that to use string interpolation you must enclose your string in **backticks** not single or double quotes.
##### Multiline strings
Another **great** feature of backtick strings is multi-line strings:
~~~
1
~~~
var template = `
~~~
2
~~~
~~~
<div>
~~~
~~~
3
~~~
~~~
<h1>
~~~
Hello
~~~
</h1>
~~~
~~~
4
~~~
~~~
<p>
~~~
This is a great website
~~~
</p>
~~~
~~~
5
~~~
~~~
</div>
~~~
~~~
6
~~~
`
~~~
7
~~~
~~~
8
~~~
// do something with `template`
Multiline strings are a huge help when we want to put strings in our code that are a little long, like templates.
### Wrapping up
There are a variety of other features in TypeScript/ES6 such as:
- Interfaces
- Generics
- Importing and Exporting Modules
- Annotations
- Destructuring
We’ll be touching on these concepts as we use them throughout the book, but for now these basics should get you started.
Let’s get back to Angular!