Skip to content

Commit 67f8f28

Browse files
committed
first cut at es6
1 parent 4279ece commit 67f8f28

11 files changed

+229
-32
lines changed

SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
* [Gettting Started](docs/getting-started.md)
44
* [Why TypeScript](docs/why-typescript.md)
5+
* [Future JavaScript Now](docs/future-javascript.md)

code/es6/test.ts

Whitespace-only changes.

code/testing.js

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
var point2D = {
2-
x: 0,
3-
y: 10,
4-
};
5-
var point3D = {
6-
x: 0,
7-
y: 10,
8-
z: 20
9-
};
10-
function iTakePoint2D(point) {
11-
}
12-
iTakePoint2D(point2D);
13-
iTakePoint2D(point3D);
14-
iTakePoint2D({
15-
x: 0
16-
});
1+
var Point = (function () {
2+
function Point(x, y) {
3+
this.x = x;
4+
this.y = y;
5+
}
6+
Point.prototype.add = function (point) {
7+
return new Point(this.x + point.x, this.y + point.y);
8+
};
9+
return Point;
10+
})();
11+
var p1 = new Point(0, 10);
12+
var p2 = new Point(10, 20);
13+
var p3 = p1.add(p2);

code/testing.ts

+9-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
interface Point2D {
2-
x: number;
3-
y: number;
1+
class Point {
2+
constructor(public x: number, public y: number) {
3+
}
4+
add(point: Point) {
5+
return new Point(this.x + point.x, this.y + point.y);
6+
}
47
}
5-
interface Point3D {
6-
x: number;
7-
y: number;
8-
z: number;
9-
}
10-
var point2D: Point2D = { x: 0, y: 10, }
11-
var point3D: Point3D = { x: 0, y: 10, z: 20 }
12-
function iTakePoint2D(point: Point2D) { /* do something */ }
138

14-
iTakePoint2D(point2D); // exact match okay
15-
iTakePoint2D(point3D); // extra information okay
16-
iTakePoint2D({ x: 0 }); // Error: missing information `y`
9+
var p1 = new Point(0, 10);
10+
var p2 = new Point(10, 20);
11+
var p3 = p1.add(p2); // {x:10,y:30}

code/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"!./node_modules/**/*.ts"
1414
],
1515
"files": [
16+
"./es6/test.ts",
1617
"./testing.ts"
1718
]
1819
}

docs/arrow-functions.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
### Arrow Functions
2+
3+
Lovingly called the *fat arrow* (becuase `->` is a thin arrow and `=>` is a fat arrow) and also called a *lambda function* (because of other languages). Another commonly used feature is the fat arrow function `()=>something`. The motivation for a *fat arrow* is:
4+
1. You don't need to keep typing `function`
5+
1. I lexically captures the meaning of `this`
6+
7+
For a language that claims to be functional, in JavaScript you tend to be typing `function` quite a lot. The fat arrow makes it simple for you to create a function
8+
```ts
9+
var inc = (x)=>x+1;
10+
```
11+
`this` has traditionally been a pain point in JavaScript. As a wise man once said "I hate JavaScript as it tends to lose the meaning of `this` all too easily". Fat arrows fix it by capturing the meaning of `this` from the surrounding context. Consider this pure JavaScript class:
12+
13+
```ts
14+
function Person(age) {
15+
this.age = age
16+
this.growOld = function(){
17+
this.age++;
18+
}
19+
}
20+
var person = new Person(1);
21+
setTimeout(person.growOld,1000);
22+
23+
setTimeout(function(){ console.log(person.age); },2000); // 1, should have been 2
24+
```
25+
If you run this code in the browser `this` within the function is going to point to `window` because `window` is going to be what executes the `growOld` function. Fix is to use an arrow function:
26+
```ts
27+
function Person(age) {
28+
this.age = age
29+
this.growOld = () => {
30+
this.age++;
31+
}
32+
}
33+
var person = new Person(1);
34+
setTimeout(person.growOld,1000);
35+
36+
setTimeout(function(){ console.log(person.age); },2000); // 2
37+
```
38+
The reason why this works is the reference to `this` is captured by the arrow function from outside the function body. This is equivalent to the following JavaScript code (which is what you would write yourself if you didn't have TypeScript):
39+
```ts
40+
function Person(age) {
41+
this.age = age
42+
var _this = this; // capture this
43+
this.growOld = function() {
44+
_this.age++; // use the captured this
45+
}
46+
}
47+
var person = new Person(1);
48+
setTimeout(person.growOld,1000);
49+
50+
setTimeout(function(){ console.log(person.age); },2000); // 2
51+
```
52+
Note that since you are using TypeScript you can be even sweeter in syntax and combine arrows with classes:
53+
```ts
54+
class Person {
55+
constructor(public age:number){}
56+
growOld = () => {
57+
this.age++;
58+
}
59+
}
60+
var person = new Person(1);
61+
setTimeout(person.growOld,1000);
62+
63+
setTimeout(function(){ console.log(person.age); },2000); // 2
64+
```
65+
66+
#### Tip on Arrow Functions
67+
Beyond the terse syntax, you only *need* to use the fat arrow if you are going to give the function to someone else to call. Effectively:
68+
```ts
69+
var growOld = person.growOld;
70+
// Then later someone else calls it:
71+
growOld();
72+
```
73+
If you are going to call it yourself, i.e.
74+
```ts
75+
person.growOld();
76+
```
77+
then `this` is going to be the correct calling context (in this example `person`).

docs/classes.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
### Classes
2+
The reason why its important to have classes in JavaScript as a first class item is that:
3+
1. People like to use classes
4+
1. Provides a consistent way for developers to use classes instead of every framework (emberjs,reactjs etc) coming up with their own version.
5+
6+
```ts
7+
class Point {
8+
constructor(public x: number, public y: number) {
9+
}
10+
add(point: Point) {
11+
return new Point(this.x + point.x, this.y + point.y);
12+
}
13+
}
14+
15+
var p1 = new Point(0, 10);
16+
var p2 = new Point(10, 20);
17+
var p3 = p1.add(p2); // {x:10,y:30}
18+
```
19+
20+
Finally JavaScript developers can *have class* :bowtie:.
21+
22+
[](Classes support inheritance)
23+
[](modifiers : public, private, protected)

docs/future-javascript.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Future JavaScript: Now
2+
One of the main selling points of TypeScript is that it allows you to use a bunch of features from ES6 in current (ES5 level) JavaScript engines (like current browsers and NodeJS). Here we deep dive into why these features are useful followed by how these features are implemented in TypeScript.
3+
4+
1. Classes
5+
2. Arrow Functions
6+
7+
## Classes
8+
{% include "./classes.md" %}
9+
10+
## Arrow Functions
11+
{% include "./arrow-functions.md" %}

docs/tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"version": "1.4.1",
3+
"compilerOptions": {
4+
"target": "es5",
5+
"module": "commonjs",
6+
"declaration": false,
7+
"noImplicitAny": false,
8+
"removeComments": true,
9+
"noLib": false
10+
},
11+
"filesGlob": [
12+
"./**/*.ts",
13+
"!./node_modules/**/*.ts"
14+
],
15+
"files": []
16+
}

docs/why-typescript.md

+72-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ We find it best to explain these in separation in first go.
1414
### Your JavaScript is TypeScript
1515
TypeScript provides compile time Type safety for your JavaScript code. This is no surprise given its name. The great thing is that the types are completely optional. Your JavaScript code `.js` file can be renamed to a `.ts` file and TypeScript will still give you back valid `.js` equivalent to the original JavaScript file. TypeScript is *intentionally* and strictly a superset of JavaScript with optional Type checking.
1616

17-
### Types are Inferred
17+
### Types can be Implicit
1818
In order to give you type safety with minimal cost of productivity during new code development. E.g. TypeScript will know that foo is of type `number` below and will give an error on the second line as shown:
1919

2020
```ts
@@ -25,7 +25,7 @@ foo = '456'; // Error: cannot assign `string` to `number`
2525
```
2626
The motivation is that if you do stuff like this, in the rest of your code you cannot be certain that `foo` is a `number` or a `string`. Such issues turn up often in large multi-file code bases. We will deep dive into the type inference rules later.
2727

28-
### Types can be specified
28+
### Types can be Explicit
2929
As we've mentioned before, TypeScript will infer as much as it can safely, however you can use annotations to:
3030
1. Help along the compiler, and more importantly the next developer who has to read your code (that might be future you!).
3131
1. Enforce that what the compiler sees is, what you thought it should see. That is your understanding of the code matches an algorithmic analysis of the code (done by the compiler).
@@ -65,9 +65,79 @@ iTakePoint2D(point3D); // extra information okay
6565
iTakePoint2D({ x: 0 }); // Error: missing information `y`
6666
```
6767

68+
### Type errors do not prevent JavaScript emit
69+
To make it easy for you to migrate your JavaScript code to TypeScript, even if there are compilation errors, by default TypeScript *will emit valid JavaScript* the best that it can. e.g.
70+
71+
```ts
72+
var foo = 123;
73+
foo = '456'; // Error: cannot assign a `string` to a `number`
74+
```
75+
76+
will emit the following js:
77+
78+
```ts
79+
var foo = 123;
80+
foo = '456';
81+
```
82+
83+
So you can incrementally upgrade your JavaScript code to TypeScript. This is very different from how many other language compilers work and is there for your ease.
84+
85+
### Types can be ambient
86+
A major design goal of TypeScript was to make it possible for you to safely and easily use existing JavaScript libraries in TypeScript. TypeScript does this by means of *declaration*. TypeScript provides you with a sliding scale of how much or how little effort you want to put in your declarations, the more effort you put the more type safety + code intelligence you get. Note that definitions for most of the popular libraries have already been written for you by the [DefinitelyTyped community](https://github.com/borisyankov/DefinitelyTyped) so for the most purposes:
87+
88+
1. The definition already exists
89+
1. You have a vast list of well reviewed TypeScript declaration templates already available.
90+
91+
As a quick example consider a trivial example of [jquery](https://jquery.com/). By default (as expect in good JS code) TypeScript expects you to declare (i.e. use `var` somewhere) before you use a variable
92+
```ts
93+
$('.awesome').show(); // Error: cannot find name `$`
94+
```
95+
As a quick fix *you can tell TypeScript* that there is indeed something called `$`:
96+
```ts
97+
declare var $:any;
98+
$('.awesome').show(); // Okay!
99+
```
100+
If you want you can build on this basic definition and provide more information to help protect you from errors:
101+
```ts
102+
declare var $:{
103+
(selector:string)=>any;
104+
};
105+
$('.awesome').show(); // Okay!
106+
$(123).show(); // Error: selector needs to be a string
107+
```
108+
109+
We will discuss the details of creating TypeScript definitions for existing JavaScript in detail later once you know more about TypeScript (e.g. stuff like `interface` and the `any`).
110+
111+
## Future JavaScript Now
112+
TypeScript provides a number of features that are planned in ES6 for current JavaScript engines (that only support ES5 etc). The typescript team is actively adding these features and this list is only going to get bigger over time and we will cover this in its own section. But just as a specimen here is an example of a class:
113+
114+
```ts
115+
class Point {
116+
constructor(public x: number, public y: number) {
117+
}
118+
add(point: Point) {
119+
return new Point(this.x + point.x, this.y + point.y);
120+
}
121+
}
122+
123+
var p1 = new Point(0, 10);
124+
var p2 = new Point(10, 20);
125+
var p3 = p1.add(p2); // {x:10,y:30}
126+
```
127+
128+
and the lovely fat arrow function:
129+
130+
```ts
131+
var inc = (x)=>x+1;
132+
```
133+
134+
### Summary
135+
In this section we have provided you with the motivation and design goals of TypeScript. With this out of the way we can dig into the nitty gritty details of TypeScript.
68136

69137
[](Interfaces are open ended)
70138
[](Type Inferernce rules)
71139
[](Cover all the annotations)
140+
[](Cover all ambients : also that there are no runtime enforcement)
141+
72142

73143
{% include "footer.md" %}

snippets/md-snippets.cson

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'.source.gfm':
2+
'include':
3+
'prefix': 'include'
4+
'body': """
5+
{% include "${1:./path}.md" %}
6+
"""

0 commit comments

Comments
 (0)