Skip to content

Commit e74908c

Browse files
authored
Merge pull request #2 from basarat/master
update from upstream
2 parents 57a0c7c + 06f94e0 commit e74908c

File tree

104 files changed

+2421
-932
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2421
-932
lines changed

.gitignore

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
.alm
1+
# Mac
22
*.DS_Store
33

4+
# IDEs
5+
.alm
6+
.vscode
7+
8+
49
# Node rules:
510
## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
611
.grunt

README.md

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
TypeScript Deep Dive
22
=======
33

4-
I've been looking at the issues that turn up commonly when people start using TypeScript. This is based on the lessons from [StackOverflow](http://stackoverflow.com/tags/typescript/topusers) / [DefinitelyTyped](https://github.com/DefinitelyTyped/) and general engagement with the [TypeScript community](https://github.com/TypeStrong/). You can [follow for updates](https://twitter.com/basarat) and [don't forget to ★ on Github](https://github.com/basarat/typescript-book) 🌹
4+
I've been looking at the issues that turn up commonly when people start using TypeScript. This is based on the lessons from [Stack Overflow](http://stackoverflow.com/tags/typescript/topusers) / [DefinitelyTyped](https://github.com/DefinitelyTyped/) and general engagement with the [TypeScript community](https://github.com/TypeStrong/). You can [follow for updates](https://twitter.com/basarat) and [don't forget to ★ on GitHub](https://github.com/basarat/typescript-book) 🌹
55

66
## Reviews
77

@@ -22,20 +22,27 @@ I've been looking at the issues that turn up commonly when people start using Ty
2222
* Guyz excellent book on Typescript(@typescriptlang) by @basarat ([link](https://twitter.com/deeinlove/status/813245965507260417))
2323
* Leaning on the legendary @basarat's "TypeScript Deep Dive" book heavily at the moment ([link](https://twitter.com/sitapati/status/814379404956532737))
2424
* numTimesPointedPeopleToBasaratsTypeScriptBook++; ([link](https://twitter.com/brocco/status/814227741696462848))
25-
* A book not only for typescript, a good one for deeper javascript knowledge as well. [link](https://www.gitbook.com/book/basarat/typescript/discussions/59)
25+
* A book not only for typescript, a good one for deeper JavaScript knowledge as well. [link](https://www.gitbook.com/book/basarat/typescript/discussions/59)
2626
* In my new job, we're using @typescriptlang, which I am new to. This is insanely helpful huge thanks, @basarat! [link](https://twitter.com/netchkin/status/855339390566096896)
2727
* Thank you for writing TypeScript Deep Dive. I have learned so much. [link](https://twitter.com/buctwbzs/status/857198618704355328?refsrc=email&s=11)
2828
* Loving @basarat's @typescriptlang online book basarat.gitbooks.io/typescript/# loaded with great recipes! [link](https://twitter.com/ericliprandi/status/857608837309677568)
2929
* Microsoft doc is great already, but if want to "dig deeper" into TypeScript I find this book of great value [link](https://twitter.com/caludio/status/876729910550831104)
3030
* Thanks, this is a great book 🤓🤓 [link](https://twitter.com/jjwonmin/status/885666375548547073)
3131
* Deep dive to typescript is awesome in so many levels. i find it very insightful. Thanks [link](https://twitter.com/orenmizr/status/891083492787970053)
32+
* @basarat's intro to @typescriptlang is still one of the best going (if not THE best) [link](https://twitter.com/stevealee/status/953953255968698368)
33+
* This is sweet! So many #typescript goodies! [link](https://twitter.com/pauliescanlon/status/989898852474998784)
3234

3335
## Get Started
3436
If you are here to read the book online [get started](http://basarat.gitbooks.io/typescript/content/docs/getting-started.html).
3537

38+
## Translations
39+
Book is completely free so you can copy paste whatever you want without requiring permission. If you have a translation you want me to link here. [Send a PR](https://github.com/basarat/typescript-book/edit/master/README.md).
40+
* [Filipino](https://github.com/themarshann/typescript-book-fil)
41+
* [Italian](https://github.com/TizioFittizio/typescript-book)
42+
3643
## Other Options
3744
You can also download one of the following:
38-
* [EPUB for iPad,iPhone,Mac](https://www.gitbook.com/download/epub/book/basarat/typescript)
45+
* [EPUB for iPad, iPhone, Mac](https://www.gitbook.com/download/epub/book/basarat/typescript)
3946
* [PDF for Windows and others](https://www.gitbook.com/download/pdf/book/basarat/typescript)
4047
* [MOBI for Kindle](https://www.gitbook.com/download/mobi/book/basarat/typescript)
4148

SUMMARY.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
* [Future JavaScript Now](docs/future-javascript.md)
1313
* [Classes](docs/classes.md)
1414
* [Classes Emit](docs/classes-emit.md)
15-
* [Classes Super](docs/classes-super.md)
1615
* [Arrow Functions](docs/arrow-functions.md)
1716
* [Rest Parameters](docs/rest-parameters.md)
1817
* [let](docs/let.md)
@@ -61,12 +60,24 @@
6160
* [Index Signatures](docs/types/index-signatures.md)
6261
* [Moving Types](docs/types/moving-types.md)
6362
* [Exception Handling](docs/types/exceptions.md)
63+
* [Mixins](docs/types/mixins.md)
6464
* [JSX](docs/jsx/tsx.md)
65+
* [React](docs/jsx/react.md)
66+
* [Non React JSX](docs/jsx/others.md)
6567
* [Options](docs/options/intro.md)
6668
* [noImplicitAny](docs/options/noImplicitAny.md)
6769
* [strictNullChecks](docs/options/strictNullChecks.md)
70+
* [Errors in TypeScript](docs/errors/main.md)
71+
* [Interpreting Errors](docs/errors/interpreting-errors.md)
72+
* [Common Errors](docs/errors/common-errors.md)
73+
* [Testing](docs/testing/intro.md)
74+
* [Jest](docs/testing/jest.md)
75+
* [Cypress](docs/testing/cypress.md)
76+
* [Tools](docs/tools/intro.md)
77+
* [Prettier](docs/tools/prettier.md)
78+
* [Husky](docs/tools/husky.md)
79+
* [Changelog](docs/tools/changelog.md)
6880
* [TIPs](docs/tips/main.md)
69-
* [Quick Object Return](docs/tips/quickObjectReturn.md)
7081
* [String Based Enums](docs/tips/stringEnums.md)
7182
* [Nominal Typing](docs/tips/nominalTyping.md)
7283
* [Stateful Functions](docs/tips/statefulFunctions.md)
@@ -77,7 +88,6 @@
7788
* [Classes are Useful](docs/tips/classesAreUseful.md)
7889
* [Avoid Export Default](docs/tips/defaultIsBad.md)
7990
* [Limit Property Setters](docs/tips/propertySetters.md)
80-
* [`null` is bad](docs/tips/null.md)
8191
* [`outFile` caution](docs/tips/outFile.md)
8292
* [JQuery tips](docs/tips/jquery.md)
8393
* [static constructors](docs/tips/staticConstructor.md)
@@ -89,7 +99,6 @@
8999
* [Create Arrays](docs/tips/create-arrays.md)
90100
* [Typesafe Event Emitter](docs/tips/typed-event.md)
91101
* [StyleGuide](docs/styleguide/styleguide.md)
92-
* [Common Errors](docs/errors/main.md)
93102
* [TypeScript Compiler Internals](docs/compiler/overview.md)
94103
* [Program](docs/compiler/program.md)
95104
* [AST](docs/compiler/ast.md)

book.json

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
2+
"language": "en",
3+
"author": "Basarat Ali Syed",
4+
"title": "TypeScript Deep Dive",
25
"plugins": ["edit-link", "github", "adsense","header"],
36
"pluginsConfig": {
47
"layout": {
File renamed without changes.

code/errors/errors.js

-2
This file was deleted.

code/errors/interpreting-errors.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export const module = 123;
2+
3+
type SomethingComplex = {
4+
foo: number,
5+
bar: string
6+
}
7+
function takeSomethingComplex(arg: SomethingComplex) {
8+
}
9+
function getBar(): string {
10+
return 'some bar';
11+
}
12+
13+
//////////////////////////////////
14+
// Example error production
15+
//////////////////////////////////
16+
const fail = {
17+
foo: 123,
18+
bar: getBar
19+
};
20+
21+
takeSomethingComplex(fail); // TS ERROR HAPPENS HERE

code/errors/tsconfig.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
{}
1+
{
2+
"compilerOptions": {
3+
"noEmit": true
4+
}
5+
}

code/types/generics.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module aaa {
77

88
const queue = new Queue();
99
queue.push(0);
10-
queue.push("1"); // Ops a mistake
10+
queue.push("1"); // Oops a mistake
1111

1212
// a developer walks into a bar
1313
console.log(queue.pop().toPrecision(1));
@@ -68,4 +68,4 @@ namespace ddd {
6868
function loadUsers() {
6969
return getJSON<LoadUsersResponse>({ url: 'https://example.com/users' });
7070
}
71-
}
71+
}

docs/arrow-functions.md

+44-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* [Tip: Arrow Function Danger](#tip-arrow-function-danger)
44
* [Tip: Libraries that use `this`](#tip-arrow-functions-with-libraries-that-use-this)
55
* [Tip: Arrow Function inheritance](#tip-arrow-functions-and-inheritance)
6+
* [Tip: Quick object return](#tip-quick-object-return)
67

78
### Arrow Functions
89

@@ -90,7 +91,7 @@ then `this` is going to be the correct calling context (in this example `person`
9091
In fact if you want `this` *to be the calling context* you should *not use the arrow function*. This is the case with callbacks used by libraries like jquery, underscore, mocha and others. If the documentation mentions functions on `this` then you should probably just use a `function` instead of a fat arrow. Similarly if you plan to use `arguments` don't use an arrow function.
9192

9293
#### Tip: Arrow functions with libraries that use `this`
93-
Many libraries do this e.g. `jQuery` iterables (one example http://api.jquery.com/jquery.each/) will use `this` to pass you the object that it is currently iterating over. In this case if you want to access the library passed `this` as well as the surrounding context just use a temp variable like `_self` like you would in the absence of arrow functions.
94+
Many libraries do this e.g. `jQuery` iterables (one example https://api.jquery.com/jquery.each/) will use `this` to pass you the object that it is currently iterating over. In this case if you want to access the library passed `this` as well as the surrounding context just use a temp variable like `_self` like you would in the absence of arrow functions.
9495

9596
```ts
9697
let _self = this;
@@ -101,8 +102,26 @@ something.each(function() {
101102
```
102103

103104
#### Tip: Arrow functions and inheritance
105+
Arrow functions as properties on classes work fine with inheritance:
104106

105-
If you have an instance method as an arrow function then it goes on `this`. Since there is only one `this` such functions cannot participate in a call to `super` (`super` only works on prototype members). You can easily get around it by creating a copy of the method before overriding it in the child.
107+
```ts
108+
class Adder {
109+
constructor(public a: number) {}
110+
add = (b: number): number => {
111+
return this.a + b;
112+
}
113+
}
114+
class Child extends Adder {
115+
callAdd(b: number) {
116+
return this.add(b);
117+
}
118+
}
119+
// Demo to show it works
120+
const child = new Child(123);
121+
console.log(child.callAdd(123)); // 246
122+
```
123+
124+
However, they do not work with the `super` keyword when you try to override the function in a child class. Properties go on `this`. Since there is only one `this` such functions cannot participate in a call to `super` (`super` only works on prototype members). You can easily get around it by creating a copy of the method before overriding it in the child.
106125

107126
```ts
108127
class Adder {
@@ -122,3 +141,26 @@ class ExtendedAdder extends Adder {
122141
}
123142
}
124143
```
144+
145+
### Tip: Quick object return
146+
147+
Sometimes you need a function that just returns a simple object literal. However, something like
148+
149+
```ts
150+
// WRONG WAY TO DO IT
151+
var foo = () => {
152+
bar: 123
153+
};
154+
```
155+
is parsed as a *block* containing a *JavaScript Label* by JavaScript runtimes (cause of the JavaScript specification).
156+
157+
> If that doesn't make sense, don't worry, as you get a nice compiler error from TypeScript saying "unused label" anyways. Labels are an old (and mostly unused) JavaScript feature that you can ignore as a modern GOTO (considered bad by experienced developers 🌹)
158+
159+
You can fix it by surrounding the object literal with `()`:
160+
161+
```ts
162+
// Correct 🌹
163+
var foo = () => ({
164+
bar: 123
165+
});
166+
```

docs/async-await.md

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## Async Await
22

3+
> [A PRO egghead video course that covers the same material](https://egghead.io/courses/async-await-using-typescript)
4+
35
As a thought experiment imagine the following: a way to tell the JavaScript runtime to pause the executing of code on the `await` keyword when used on a promise and resume *only* once (and if) the promise returned from the function is settled:
46

57
```ts
@@ -63,7 +65,7 @@ function delay(milliseconds: number, count: number): Promise<number> {
6365
});
6466
}
6567

66-
// async function always return a Promise
68+
// async function always returns a Promise
6769
async function dramaticWelcome(): Promise<void> {
6870
console.log("Hello");
6971

@@ -96,7 +98,7 @@ function delay(milliseconds, count) {
9698
}, milliseconds);
9799
});
98100
}
99-
// async function always return a Promise
101+
// async function always returns a Promise
100102
function dramaticWelcome() {
101103
return __awaiter(this, void 0, void 0, function* () {
102104
console.log("Hello");
@@ -157,7 +159,7 @@ function delay(milliseconds, count) {
157159
}, milliseconds);
158160
});
159161
}
160-
// async function always return a Promise
162+
// async function always returns a Promise
161163
function dramaticWelcome() {
162164
return __awaiter(this, void 0, void 0, function () {
163165
var i, count;
@@ -189,9 +191,9 @@ dramaticWelcome();
189191
You can see full example [here][asyncawaites5code].
190192

191193

192-
**Note**: for both target scenarios, we need to make sure our run-time has an ECMAScript-compliant Promise available globally. That might involve grabbing a polyfill for Promise. We also need to make sure that TypeScript knows Promise exists by setting your lib flag to something like "dom", "es2015" or "dom", "es2015.promise", "es5".
194+
**Note**: for both target scenarios, we need to make sure our run-time has an ECMAScript-compliant Promise available globally. That might involve grabbing a polyfill for Promise. We also need to make sure that TypeScript knows Promise exists by setting our lib flag to something like "dom", "es2015" or "dom", "es2015.promise", "es5".
193195
**We can see what browsers DO have Promise support (native and polyfilled) [here](https://kangax.github.io/compat-table/es6/#test-Promise).**
194196

195197
[generators]:./generators.md
196-
[asyncawaites5code]:../code/async-await/es5/asyncAwaitES5.js
197-
[asyncawaites6code]:../code/async-await/es6/asyncAwaitES6.js
198+
[asyncawaites5code]:https://cdn.rawgit.com/basarat/typescript-book/705e4496/code/async-await/es5/asyncAwaitES5.js
199+
[asyncawaites6code]:https://cdn.rawgit.com/basarat/typescript-book/705e4496/code/async-await/es6/asyncAwaitES6.js

docs/classes-emit.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Point.prototype.add = function (point) {
1010
};
1111
```
1212

13-
The reason its wrapped in an Immediately-Invoked Function Expression (IIFE) i.e.
13+
The reason it's wrapped in an Immediately-Invoked Function Expression (IIFE) i.e.
1414

1515
```ts
1616
(function () {
@@ -81,7 +81,7 @@ delete foo.__proto__.bar; // remove from foo.__proto__
8181
console.log(foo.bar); // undefined
8282
```
8383

84-
Cool so you understand `__proto__`. Another useful information is that all `function`s in JavaScript have a property called `prototype` and that it has a member `constructor` pointing back to the function. This is shown below:
84+
Cool so you understand `__proto__`. Another useful fact is that all `function`s in JavaScript have a property called `prototype` and that it has a member `constructor` pointing back to the function. This is shown below:
8585

8686
```ts
8787
function Foo() { }
@@ -121,7 +121,7 @@ That's it. Now look at the following straight out of `__extends`. I've taken the
121121

122122
Reading this function in reverse the `d.prototype = new __()` on line 3 effectively means `d.prototype = {__proto__ : __.prototype}` (because of the effect of `new` on `prototype` and `__proto__`), combining it with the previous line (i.e. line 2 `__.prototype = b.prototype;`) you get `d.prototype = {__proto__ : b.prototype}`.
123123

124-
But wait, we wanted `d.prototype.__proto__` i.e. just the proto changed and maintain the old `d.prototype.constructor`. This is where the significance of the first line (i.e. `function __() { this.constructor = d; }`) comes in. Here we will effectively have `d.prototype = {__proto__ : __.prototype, d.constructor = d}` (because of the effect of `new` on `this` inside the called function). So, since we restore `d.prototype.constructor`, the only thing we have truly mutated is the `__proto__` hence `d.prototype.__proto__ = b.prototype`.
124+
But wait, we wanted `d.prototype.__proto__` i.e. just the proto changed and maintain the old `d.prototype.constructor`. This is where the significance of the first line (i.e. `function __() { this.constructor = d; }`) comes in. Here we will effectively have `d.prototype = {__proto__ : __.prototype, constructor : d}` (because of the effect of `new` on `this` inside the called function). So, since we restore `d.prototype.constructor`, the only thing we have truly mutated is the `__proto__` hence `d.prototype.__proto__ = b.prototype`.
125125

126126
#### `d.prototype.__proto__ = b.prototype` significance
127127

docs/classes-super.md

-62
This file was deleted.

docs/compiler/ast-tip-children.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArr
2323
// .... lots more
2424
```
2525
26-
Basically it checks `node.kind` and based on that assumes an interface offered by the `node` and calls the `cbNode` on the children. Note, however that this function doesn't call `visitNode` for *all* children (e.g. SyntaxKind.SemicolonToken). If you want *all* the children of a node in the AST just call `.getChildren` member function of the `Node`.
26+
Basically, it checks `node.kind` and based on that assumes an interface offered by the `node` and calls the `cbNode` on the children. However, note that this function doesn't call `visitNode` for *all* children (e.g. SyntaxKind.SemicolonToken). If you want *all* the children of a node in the AST just call `.getChildren` member function of the `Node`.
2727
2828
E.g. here is a function that prints the verbose `AST` of a node:
2929

docs/compiler/ast-tip-syntaxkind.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const enum SyntaxKind {
1010
// ... LOTS more
1111
```
1212
13-
It's a `const enum` (a concept [we covered previously](../enums.md)) so that it gets *inlined* (e.g. `ts.SyntaxKind.EndOfFileToken` becomes `1`) and we don't get a dereferencing cost when working with the AST. However the compiler is compiled with `--preserveConstEnums` compiler flag so that the enum *is still available at runtime*. So in JavaScript you can use `ts.SyntaxKind.EndOfFileToken` if you want. Additionally you can convert these enum members to display strings using the following function:
13+
It's a `const enum` (a concept [we covered previously](../enums.md)) so that it gets *inlined* (e.g. `ts.SyntaxKind.EndOfFileToken` becomes `1`) and we don't get a dereferencing cost when working with the AST. However, the compiler is compiled with `--preserveConstEnums` compiler flag so that the enum *is still available at runtime*. So in JavaScript you can use `ts.SyntaxKind.EndOfFileToken` if you want. Additionally you can convert these enum members to display strings using the following function:
1414
1515
```ts
1616
export function syntaxKindToName(kind: ts.SyntaxKind) {

docs/compiler/ast-trivia.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
### Trivia
2-
Trivia (called that because it's `trivial`) represent the parts of the source text that are largely insignificant for normal understanding of the code. For example; whitespace, comments, and even conflict markers. Trivia is *not stored* in the AST (to keep it lightweight). However it can be fetched *on demand* using a few `ts.*` APIs.
2+
Trivia (called that because it's `trivial`) represent the parts of the source text that are largely insignificant for normal understanding of the code. For example; whitespace, comments, and even conflict markers. Trivia is *not stored* in the AST (to keep it lightweight). However, it can be fetched *on demand* using a few `ts.*` APIs.
33

44
Before we show them you need to understand the following:
55

0 commit comments

Comments
 (0)