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