Skip to content

Commit 35ea057

Browse files
author
Orta
authored
Merge pull request #241 from microsoft/compiler_docs
Start migrating my tsc notes to the wiki
2 parents 54f7390 + 435cdaf commit 35ea057

32 files changed

+1521
-17
lines changed

.github/workflows/sync.yml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- uses: actions/checkout@v1
12-
12+
1313
# Setup Git
1414
- run: git config user.name "typescript-bot"
1515
- run: git config user.email "[email protected]"
16-
# Remove the un-auth'd origin
17-
- run: git remote remove origin
18-
# Switch to authed remotes for both the - and the .
19-
- run: |
20-
git remote add origin https://[email protected]/microsoft/TypeScript-wiki.git > /dev/null 2>&1
21-
git remote add upstream https://[email protected]/microsoft/TypeScript.wiki.git > /dev/null 2>&1
16+
17+
# Add the authed remotes for .
18+
- run: git remote add upstream https://[email protected]/microsoft/TypeScript.wiki.git > /dev/null 2>&1
2219
env:
2320
GITHUB_TOKEN: ${{ secrets.TS_BOT_TOKEN }}
2421

25-
- run: git fetch origin
26-
- run: git fetch upstream
27-
# Merge them all together
28-
- run: git merge upstream/master --no-edit
29-
# Push them both
30-
- run: git push upstream HEAD:master > /dev/null 2>&1
22+
# Update search links from the origin repo before pushing to the upstream
23+
- run: git clone -–depth 1 https://github.com/microsoft/TypeScript.git
24+
- run: node scripts/convertRelativeLinksToHardcoded.js **/*.md --write
25+
- run: rm -rf TypeScript
26+
27+
- run: git add .
28+
- run: git commit --amend --no-edit
29+
30+
# Push to the auth'd branch
31+
- run: git push upstream HEAD:master -f > /dev/null 2>&1

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
yarn.lock
2+
node_modules/
3+
package-lock.json
4+
TypeScript

Home.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
The TypeScript Wiki is for people who are interested in:
22

3-
- Debugging TypeScript problems
4-
- Using the compiler API
5-
- Wanting to contribute to the TypeScript codebase
3+
- [Debugging TypeScript problems](./debugging)
4+
- [Using the compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API)
5+
- [Wanting to contribute to the TypeScript codebase or to understand the compiler](./compiler)
66

77
It is also used as a scratch-pad for one-off links which are useful when triaging GitHub issues. For example the [[FAQ]]
88

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ in a GitHub Action in [`.github/workflows/sync.yml`](.github/workflows/sync.yml)
66

77
The wiki root is [Home.md](./Home.md).
88

9-
109
# Contributing
1110

1211
This project welcomes contributions and suggestions. Most contributions require you to agree to a

compiler/CONTRIBUTING.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
This page follows on from [README.md](./README.md).
2+
3+
### Getting set up
4+
5+
To get your VS Code env working smoothly, set up the per-user config
6+
7+
- Set up your `.vscode/launch.json` by running: `cp ./vscode/launch.template.json ./vscode/launch.json`
8+
- Set up your `.vscode/settings.json` by running: `cp ./vscode/settings.template.json ./vscode/settings.json`
9+
10+
In the `launch.json` I duplicate the configuration, and change `"${fileBasenameNoExtension}",` to be whatever test
11+
file I am currently working on.
12+
13+
### Learn the debugger
14+
15+
You'll probably spend a good amount of time in it, if this is completely new to you. Here is a video from
16+
[@alloy](https://github.com/alloy) covering all of the usage of the debugger inside VS Code and how it works.
17+
18+
To test it out, open up `src/compiler/checker.ts` find `function checkSourceFileWorker(node: SourceFile) {` and
19+
add a debugger on the first line in the code. If you open up `tests/cases/fourslash/getDeclarationDiagnostics.ts`
20+
and then run your new debugging launch task `Mocha Tests (currently opened test)`. It will switch into the
21+
debugger and hit a breakpoint in your TypeScript.
22+
23+
You'll probably want to add the following to your watch section in VS Code:
24+
25+
- `node.__debugKind`
26+
- `node.__debugGetText()`
27+
- `source.symbol.declarations[0].__debugKind`
28+
- `target.symbol.declarations[0].__debugKind`
29+
30+
This is really useful for keeping track of changing state, and it's pretty often that those are the names of
31+
things you're looking for.
32+
33+
### Getting started
34+
35+
You can learn about the different ways to [write a test here](./systems/testing) to try and re-produce a bug. It
36+
might be a good idea to look in the recently closed PRs to find something small which adds a test case, then read
37+
the test and the code changes to get used to the flow.

compiler/GLOSSARY.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
### Terminology from inside the codebase
2+
3+
You can also see the [Data Structures](https://github.com/microsoft/TypeScript/wiki/Architectural-Overview#data-structures) section of the architecture overview.
4+
5+
- `Parser` - Takes source code and tries to convert it into an in-memory AST representation which you can work
6+
with in the compiler. Also: [see Parser](https://basarat.gitbooks.io/typescript/docs/compiler/parser.html)
7+
- `Scanner` - Used by the parser to convert a string an chops into tokens in a linear fashion, then it's up to a
8+
parser to tree-ify them. Also: [see Scanner](https://basarat.gitbooks.io/typescript/docs/compiler/scanner.html)
9+
- `Binder` - Creates a symbol map and uses the AST to provide the type system
10+
[See Binder](https://basarat.gitbooks.io/typescript/docs/compiler/binder.htmlhttps://basarat.gitbooks.io/typescript/docs/compiler/binder.html)
11+
- `Checker` - Takes the AST, symbols and does the type checking and inference -
12+
[See Checker](https://basarat.gitbooks.io/typescript/docs/compiler/checker.html)
13+
- `Token` - A set of characters with some kind of semantic meaning, a parser generates a set of tokens
14+
- `AST` - An abstract syntax tree. Basically the in-memory representation of all the identifiers as a tree of
15+
tokens.
16+
- `Node` - An object that lives inside the tree
17+
- `Location` / `Range`
18+
- `Freshness` - When a literal type is first created and not expanded by hitting a mutable location, see [Widening
19+
and Narrowing in TypeScript][wnn].
20+
- `Symbol` - The binder creates symbols which connects declarations together
21+
22+
### Type stuff which can be see outside the compilers
23+
24+
- `Structural Type System` - A school of types system where the way types are compared is via the structure of
25+
their properties.
26+
27+
For example:
28+
29+
```ts
30+
interface Duck {
31+
hasBeak: boolean;
32+
flap: () => void;
33+
}
34+
35+
interface Bird {
36+
hasBeak: boolean;
37+
flap: () => void;
38+
}
39+
```
40+
41+
These two are the exact same inside TypeScript. The basic rule for TypeScript’s structural type system is that
42+
`x` is compatible with `y` if `y` has at least the same members as `x`.
43+
44+
* `Literal` - A literal type is a type that only has a single value, e.g. `true`, `1`, `"abc"`, `undefined`.
45+
46+
For immutable objects, TypeScript creates a literal type which is is the value. For mutable objects TypeScript
47+
uses the general type that the literal matches. See [#10676](https://github.com/Microsoft/TypeScript/pull/10676)
48+
for a longer explanation.
49+
50+
```ts
51+
// The types are the literal:
52+
const c1 = 1; // Type 1
53+
const c2 = c1; // Type 1
54+
const c3 = "abc"; // Type "abc"
55+
const c4 = true; // Type true
56+
const c5 = c4 ? 1 : "abc"; // Type 1 | "abc"
57+
58+
// The types are the class of the literal, because let allows it to change
59+
let v1 = 1; // Type number
60+
let v2 = c2; // Type number
61+
let v3 = c3; // Type string
62+
let v4 = c4; // Type boolean
63+
let v5 = c5; // Type number | string
64+
```
65+
66+
- `Control Flow Analysis` - using the natural branching and execution path of code to change the types at
67+
different locations in your source code by static analysis.
68+
69+
```ts
70+
type Bird = { color: string, flaps: true };
71+
type Tiger = { color: string, stripes: true };
72+
declare animal: Bird | Tiger
73+
74+
if ("stripes" in animal) {
75+
// Inside here animal is only a tiger, because TS could figure out that
76+
// the only way you could get here is when animal is a tiger and not a bird
77+
}
78+
```
79+
80+
- `Generics` - A way to have variables inside a type system.
81+
82+
```ts
83+
function first(array: any[]): any {
84+
return array[0];
85+
}
86+
```
87+
88+
You want to be able to pass a variable type into this function, so you annotate the function with angle brackets
89+
and a _type parameter_:
90+
91+
```ts
92+
function first<T>(array: T[]): T {
93+
return array[0];
94+
}
95+
```
96+
97+
This means the return type of `first` is the same as the type of the array elements passed in. (These can start
98+
looking very complicated over time, but the principle is the same; it just looks more complicated because of the
99+
single letter.) Generic functions should always use their type parameters in more than one position (e.g. above,
100+
`T` is used both in the type of the `array` parameter and in the function’s return type). This is the heart of
101+
what makes generics useful—they can specify a _relationship_ between two types (e.g., a function’s output is the
102+
same as input, or a function’s two inputs are the same type). If a generic only uses its type parameter once, it
103+
doesn’t actually need to be generic at all, and indeed some linters will warn that it’s a _useless generic_.
104+
105+
Type parameters can usually be inferred from function arguments when calling generics:
106+
107+
```ts
108+
first([1, 2, 3]); // 'T' is inferred as 'number'
109+
```
110+
111+
It’s also possible to specify them explicitly, but it’s preferable to let inference work when possible:
112+
113+
```ts
114+
first<string>(["a", "b", "c"]);
115+
```
116+
117+
* `Outer type parameter` - A type parameter declared in a parent generic construct:
118+
119+
```ts
120+
class Parent<T> {
121+
method<U>(x: T, y: U): U {
122+
// 'T' is an *outer* type parameter of 'method'
123+
// 'U' is a *local* type parameter of 'method'
124+
}
125+
}
126+
```
127+
128+
* `Narrowing` - Taking a union of types and reducing it to fewer options.
129+
130+
A great case is when using `--strictNullCheck` when using control flow analysis
131+
132+
```ts
133+
// I have a dog here, or I don't
134+
declare const myDog: Dog | undefined;
135+
136+
// Outside the if, myDog = Dog | undefined
137+
if (dog) {
138+
// Inside the if, myDog = Dog
139+
// because the type union was narrowed via the if statement
140+
dog.bark();
141+
}
142+
```
143+
144+
- `Expanding` - The opposite of narrowing, taking a type and converting it to have more potential values.
145+
146+
```ts
147+
const helloWorld = "Hello World"; // Type; "Hello World"
148+
149+
let onboardingMessage = helloWorld; // Type: string
150+
```
151+
152+
When the `helloWorld` constant was re-used in a mutable variable `onboardingMessage` the type which was set is an
153+
expanded version of `"Hello World"` which went from one value ever, to any known string.
154+
155+
- `Transient` - unsure
156+
157+
- `Partial Type` -
158+
- `Synthetic` -
159+
- `Union Types`
160+
- `Enum`
161+
- `Discriminant`
162+
- `Intersection`
163+
- `Indexed Type` - A way to access subsets of your existing types.
164+
165+
```ts
166+
interface User {
167+
profile: {
168+
name: string;
169+
email: string;
170+
bio: string;
171+
};
172+
account: {
173+
id: string;
174+
signedUpForMailingList: boolean;
175+
};
176+
}
177+
178+
type UserProfile = User["profile"]; // { name: string, email: string, bio: string }
179+
type UserAccount = User["account"]; // { id: string, signedUpForMailingList: string }
180+
```
181+
182+
This makes it easier to keep a single source of truth in your types.
183+
184+
- `Index Signatures` - A way to tell TypeScript that you might not know the keys, but you know the type of values
185+
of an object.
186+
187+
```ts
188+
interface MySettings {
189+
[index: string]: boolean;
190+
}
191+
192+
declare function getSettings(): MySettings;
193+
const settings = getSettings();
194+
const shouldAutoRotate = settings.allowRotation; // boolean
195+
```
196+
197+
- `IndexedAccess` - ( https://github.com/Microsoft/TypeScript/pull/30769 )
198+
- `Conditional Types`
199+
- `Contextual Types`
200+
- `Substitution`
201+
- `NonPrimitive`
202+
- `Instantiable`
203+
- `Tuple` - A mathematical term for a finite ordered list. Like an array but with a known length.
204+
205+
TypeScript lets you use these as convenient containers with known types.
206+
207+
```ts
208+
// Any item has to say what it is, and whether it is done
209+
type TodoListItem = [string, boolean];
210+
211+
const chores: TodoListItem[] = [["read a book", true], ["done dishes", true], ["take the dog out", false]];
212+
```
213+
214+
Yes, you could use an object for each item in this example, but tuples are there when it fits your needs.
215+
216+
- `Mapped Type` - A type which works by taking an existing type and creating a new version with modifications.
217+
218+
```ts
219+
type Readonly<T> = { readonly [P in keyof T]: T[P] };
220+
221+
// Map for every key in T to be a readonly version of it
222+
// e.g.
223+
interface Dog {
224+
furColor: string;
225+
hasCollar: boolean;
226+
}
227+
228+
// Using this
229+
type ReadOnlyDog = Readonly<Dog>;
230+
231+
// Would be
232+
interface ReadonlyDog {
233+
readonly furColor: string;
234+
readonly hasCollar: boolean;
235+
}
236+
```
237+
238+
This can work where you
239+
240+
- `Type Assertion` - override its inferred and analyzed view of a type
241+
242+
```ts
243+
interface Foo {
244+
bar: number;
245+
bas: string;
246+
}
247+
var foo = {} as Foo;
248+
foo.bar = 123;
249+
foo.bas = "hello";
250+
```
251+
252+
- `Incremental Parsing` - Having an editor pass a range of edits, and using that range to invalidate a cache of
253+
the AST. Re-running the type checker will keep the out of range nodes and only parse the new section.
254+
- `Incremental Compiling` - The compiler keeps track of all compilation hashes, and timestamps when a file has
255+
been transpiled. Then when a new module is changed, it will use the import/export dependency graph to invalidate
256+
and re-compile only the affected code.
257+
258+
### Rarely heard
259+
260+
- `Deferred` - A type might not be able to infer yet, because it is waiting for other types to be inferred first
261+
- `Homomorphic` - A map between objects which means that the mapping applies to every property of the object
262+
263+
### JS Internals Specifics
264+
265+
[`Statement`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements) - "JavaScript
266+
applications consist of statements with an appropriate syntax. A single statement may span multiple lines.
267+
Multiple statements may occur on a single line if each statement is separated by a semicolon. This isn't a
268+
keyword, but a group of keywords."
269+
270+
[wnn]: https://github.com/sandersn/manual/blob/master/Widening-and-Narrowing-in-Typescript.md

0 commit comments

Comments
 (0)