You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/arrow-functions.md
+20-20
Original file line number
Diff line number
Diff line change
@@ -1,42 +1,42 @@
1
1
### Arrow Functions
2
2
3
-
Lovingly called the *fat arrow* (because `->` 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:
3
+
Lovingly called the *fat arrow* (because `->` 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
4
1. You don't need to keep typing `function`
5
5
2. It lexically captures the meaning of `this`
6
6
2. It lexically captures the meaning of `arguments`
7
7
8
-
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
+
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
9
9
```ts
10
10
var inc = (x)=>x+1;
11
11
```
12
-
`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
+
`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:
13
13
14
14
```ts
15
15
function Person(age) {
16
16
this.age=age
17
-
this.growOld=function(){
17
+
this.growOld=function(){
18
18
this.age++;
19
19
}
20
20
}
21
-
var person =newPerson(1);
21
+
var person =newPerson(1);
22
22
setTimeout(person.growOld,1000);
23
23
24
-
setTimeout(function(){ console.log(person.age); },2000); // 1, should have been 2
24
+
setTimeout(function(){ console.log(person.age); },2000); // 1, should have been 2
25
25
```
26
-
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
+
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:
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
+
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):
Copy file name to clipboardExpand all lines: docs/classes.md
+7-7
Original file line number
Diff line number
Diff line change
@@ -99,7 +99,7 @@ foo.z; // ERROR : protected
99
99
100
100
// EFFECT ON CHILD CLASSES
101
101
classFooChildextendsFooBase {
102
-
constructor(){
102
+
constructor(){
103
103
super();
104
104
this.x; // okay
105
105
this.y; // ERROR: private
@@ -120,18 +120,18 @@ As always these modifiers work for both member properties and member functions.
120
120
Having a member in a class and initializing it like below:
121
121
122
122
```ts
123
-
classFoo{
123
+
classFoo{
124
124
x:number;
125
-
constructor(x:number){
125
+
constructor(x:number){
126
126
this.x=x;
127
127
}
128
128
}
129
129
```
130
130
is such a common pattern that TypeScript provides a shorthand where you can prefix the member with an *access modifier* and it is automatically declared on the class and copied from the constructor. So the previous example can be re-written as (notice `public x:number`):
131
131
132
132
```ts
133
-
classFoo{
134
-
constructor(publicx:number){
133
+
classFoo{
134
+
constructor(publicx:number){
135
135
}
136
136
}
137
137
```
@@ -140,9 +140,9 @@ class Foo{
140
140
This is a nifty feature supported by TypeScript (from ES7 actually). You can initialize any member of the class outside the class constructor, useful to provide default (notice `members = []`)
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`.
27
27
28
-
E.g. here is a function that prints the verbose `AST` of a node:
28
+
E.g. here is a function that prints the verbose `AST` of a node:
29
29
30
30
```ts
31
31
function printAllChildren(node:ts.Node, depth=0) {
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 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 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:
14
14
15
15
```ts
16
16
export function syntaxKindToName(kind: ts.SyntaxKind) {
Copy file name to clipboardExpand all lines: docs/compiler/binder-container.md
+2-3
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
### Container
2
2
3
-
An AST node can be a container. This determines the kinds of `SymbolTables` the Node and associated Symbol will have. Container is an abstract concept (i.e. has no associated data structure). The concept is driven by a few things, one being the `ContainerFlags` enum. The function `getContainerFlags` (in `binder.ts`) drives this flag and is presented below:
3
+
An AST node can be a container. This determines the kinds of `SymbolTables` the Node and associated Symbol will have. Container is an abstract concept (i.e. has no associated data structure). The concept is driven by a few things, one being the `ContainerFlags` enum. The function `getContainerFlags` (in `binder.ts`) drives this flag and is presented below:
4
4
5
5
```ts
6
6
function getContainerFlags(node:Node):ContainerFlags {
@@ -62,7 +62,7 @@ function getContainerFlags(node: Node): ContainerFlags {
62
62
}
63
63
```
64
64
65
-
It is *only* invoked from the binder's `bindChildren` function which sets up a node as a `container` and/or a `blockScopedContainer` depending upon the evaluation of the `getContainerFlags` function. The function `bindChildren` is presented below:
65
+
It is *only* invoked from the binder's `bindChildren` function which sets up a node as a `container` and/or a `blockScopedContainer` depending upon the evaluation of the `getContainerFlags` function. The function `bindChildren` is presented below:
66
66
67
67
```ts
68
68
// All container nodes are kept on a linked list in declaration order. This list is used by
@@ -121,4 +121,3 @@ function bindChildren(node: Node) {
121
121
```
122
122
123
123
As you might recall from section on binder functions : `bindChildren` is called from the `bind` function. So we have the recursive bindig setup : `bind` calls `bindChildren` calls `bind` for each child.
Copy file name to clipboardExpand all lines: docs/compiler/binder-declarations.md
+4-4
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
### Symbols and Declarations
2
-
Linking between a `node` and a `symbol` is performed by a few functions. One function that is used to bind the `SourceFile` node to the source file Symbol (in case of an external module) is the `addDeclarationToSymbol` function
2
+
Linking between a `node` and a `symbol` is performed by a few functions. One function that is used to bind the `SourceFile` node to the source file Symbol (in case of an external module) is the `addDeclarationToSymbol` function
3
3
4
-
Note : the `Symbol` for an external module source file is setup as `flags : SymbolFlags.ValueModule` and `name: '"' + removeFileExtension(file.fileName) + '"'`).
4
+
Note : the `Symbol` for an external module source file is setup as `flags : SymbolFlags.ValueModule` and `name: '"' + removeFileExtension(file.fileName) + '"'`).
5
5
6
6
```ts
7
7
function addDeclarationToSymbol(symbol:Symbol, node:Declaration, symbolFlags:SymbolFlags) {
@@ -28,8 +28,8 @@ function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags:
28
28
}
29
29
```
30
30
31
-
The important linking portions:
32
-
* creates a link to the Symbol from the AST node (`node.symbol`).
31
+
The important linking portions:
32
+
* creates a link to the Symbol from the AST node (`node.symbol`).
33
33
* add the node as *one of* the declarations of the Symbol (`symbol.declarations`).
Copy file name to clipboardExpand all lines: docs/compiler/binder-diagnostics.md
+3-3
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
1
### Binder Error Reporting
2
2
3
-
Binding errors are added to the sourceFile's list of `bindDiagnostics`.
3
+
Binding errors are added to the sourceFile's list of `bindDiagnostics`.
4
4
5
-
An example error detected during binding is the use of `eval` or `arguments` as a variable name in `use strict` scenario. The relevant code is presented in its entirety below (`checkStrictModeEvalOrArguments` is called from multiple places, call stacks originating from `bindWorker` which calls different functions for different node `SyntaxKind`):
5
+
An example error detected during binding is the use of `eval` or `arguments` as a variable name in `use strict` scenario. The relevant code is presented in its entirety below (`checkStrictModeEvalOrArguments` is called from multiple places, call stacks originating from `bindWorker` which calls different functions for different node `SyntaxKind`):
6
6
7
7
```ts
8
8
function checkStrictModeEvalOrArguments(contextNode:Node, name:Node) {
@@ -36,4 +36,4 @@ function getStrictModeEvalOrArgumentsMessage(node: Node) {
Copy file name to clipboardExpand all lines: docs/compiler/binder-functions.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ Basically checks if the `file.locals` is defined, if not it hands over to (a loc
6
6
7
7
Note: `locals` is defined on `Node` and is of type `SymbolTable`. Note that `SourceFile` is also a `Node` (in fact a root node in the AST).
8
8
9
-
TIP: local functions are used heavily within the TypeScript compiler. A local function very likely uses variables from the parent function (captured by closure). In the case of `bind` (a local function within `bindSourceFile`) it (or function it calls) will setup the `symbolCount` and `classifiableNames` among others, that are then stored on the returned `SourceFile`.
9
+
TIP: local functions are used heavily within the TypeScript compiler. A local function very likely uses variables from the parent function (captured by closure). In the case of `bind` (a local function within `bindSourceFile`) it (or function it calls) will setup the `symbolCount` and `classifiableNames` among others, that are then stored on the returned `SourceFile`.
10
10
11
11
#### `bind`
12
12
Bind takes any `Node` (not just `SourceFile`). First thing it does is assign the `node.parent` (if `parent` variable has been setup ... which again is something the binder does during its processing within the `bindChildren` function), then hands off to `bindWorker` which does the *heavy* lifting. Finally it calls `bindChildren` (a function that simply stores the binder state e.g. current `parent` within its function local vars, then calls `bind` on each child, and then restores the binder state). Now lets look at `bindWorker` which is the more interesting function.
@@ -15,7 +15,7 @@ Bind takes any `Node` (not just `SourceFile`). First thing it does is assign the
15
15
This function switches on `node.kind` (of type `SyntaxKind`) and delegates work to the appropriate `bindFoo` function (also defined within `binder.ts`). For example if the `node` is a `SourceFile` it calls (eventually and only if its an external file module) `bindAnonymousDeclaration`
16
16
17
17
#### `bindFoo` functions
18
-
There are few pattern common to `bindFoo` functions as well as some utility functions that these use. One function that is almost always used is the `createSymbol` function. It is presented in its entirety below:
18
+
There are few pattern common to `bindFoo` functions as well as some utility functions that these use. One function that is almost always used is the `createSymbol` function. It is presented in its entirety below:
19
19
20
20
```ts
21
21
function createSymbol(flags:SymbolFlags, name:string):Symbol {
Which basically merges all the `global` symbols into the `let globals: SymbolTable = {};` (in `createTypeChecker`) SymbolTable. `mergeSymbolTable` primarily calls `mergeSymbol`.
13
+
Which basically merges all the `global` symbols into the `let globals: SymbolTable = {};` (in `createTypeChecker`) SymbolTable. `mergeSymbolTable` primarily calls `mergeSymbol`.
Copy file name to clipboardExpand all lines: docs/compiler/checker.md
+7-8
Original file line number
Diff line number
Diff line change
@@ -16,19 +16,18 @@ program.getTypeChecker ->
16
16
### Association with Emitter
17
17
True type checking happens once a call is made to `getDiagnostics`. This function is called e.g. once a request is made to `Program.emit`, in which case the checker returns an `EmitResolver` (progarm calls the checkers `getEmitResolver` function) which is just a set of functions local to `createTypeChecker`. We will mention this again when we look at the emitter.
18
18
19
-
Here is the call stack right down to `checkSourceFile` (a function local to `createTypeChecker`).
19
+
Here is the call stack right down to `checkSourceFile` (a function local to `createTypeChecker`).
20
20
21
21
```
22
-
program.emit ->
23
-
emitWorker (program local) ->
22
+
program.emit ->
23
+
emitWorker (program local) ->
24
24
createTypeChecker.getEmitResolver ->
25
25
// First call the following functions local to createTypeChecker
26
-
call getDiagnostics ->
27
-
getDiagnosticsWorker ->
26
+
call getDiagnostics ->
27
+
getDiagnosticsWorker ->
28
28
checkSourceFile
29
-
29
+
30
30
// then
31
-
return resolver
31
+
return resolver
32
32
(already initialized in createTypeChecker using a call to local createResolver())
Copy file name to clipboardExpand all lines: docs/compiler/emitter.md
+3-3
Original file line number
Diff line number
Diff line change
@@ -7,11 +7,11 @@ There are two `emitters` provided with the TypeScript compiler:
7
7
We will look at `emitter.ts` in this section.
8
8
9
9
### Usage by `program`
10
-
Program provides an `emit` function. This function primarily delegates to `emitFiles` function in `emitter.ts`. Here is the call stack:
10
+
Program provides an `emit` function. This function primarily delegates to `emitFiles` function in `emitter.ts`. Here is the call stack:
11
11
12
12
```
13
-
Program.emit ->
13
+
Program.emit ->
14
14
`emitWorker` (local in program.ts createProgram) ->
15
15
`emitFiles` (function in emitter.ts)
16
16
```
17
-
One thing that the `emitWorker` provides to the emitter (via an argument to `emitFiles`) is an `EmitResolver`. `EmitResolver` is provided by the program's TypeChecker, basically it a subset of *local* functions from `createChecker`.
17
+
One thing that the `emitWorker` provides to the emitter (via an argument to `emitFiles`) is an `EmitResolver`. `EmitResolver` is provided by the program's TypeChecker, basically it a subset of *local* functions from `createChecker`.
0 commit comments