{"action":"opened","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/7689","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/7689/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/7689/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/7689/events","html_url":"https://github.com/Microsoft/TypeScript/issues/7689","id":143586130,"number":7689,"title":"Design Meeting Notes for 3/25/2016","user":{"login":"DanielRosenwasser","id":972891,"avatar_url":"https://avatars.githubusercontent.com/u/972891?v=3","gravatar_id":"","url":"https://api.github.com/users/DanielRosenwasser","html_url":"https://github.com/DanielRosenwasser","followers_url":"https://api.github.com/users/DanielRosenwasser/followers","following_url":"https://api.github.com/users/DanielRosenwasser/following{/other_user}","gists_url":"https://api.github.com/users/DanielRosenwasser/gists{/gist_id}","starred_url":"https://api.github.com/users/DanielRosenwasser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DanielRosenwasser/subscriptions","organizations_url":"https://api.github.com/users/DanielRosenwasser/orgs","repos_url":"https://api.github.com/users/DanielRosenwasser/repos","events_url":"https://api.github.com/users/DanielRosenwasser/events{/privacy}","received_events_url":"https://api.github.com/users/DanielRosenwasser/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Design%20Notes","name":"Design Notes","color":"bfdadc"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-03-25T20:11:59Z","updated_at":"2016-03-25T20:11:59Z","closed_at":null,"body":"# `this`-types for functions (#6739)\r\n\r\n* Defines ability to define type of `this` for the scope of a function.\r\n* If you're in a class, `this` is assumed to have the type of the class itself.\r\n    * You can still override this by giving an explicit type to `this`.\r\n\r\n## Strict `this` checks\r\n\r\n* Problem: cognitive burden by creating a distinction between types of methods and properties with function types.\r\n\r\n* Looked at performance against `master.`\r\n    * Lots of variance.\r\n    * (Insert graph here).\r\n    * But does look like there is a consistent perf hit.\r\n    * \\<10%, >5%.\r\n\r\n* Incompatible with old code in some cases.\r\n    * Need to update `.d.ts` files.\r\n    * Huge undertaking.\r\n    * Already tons of stuff for \r\n\r\n* Options in light of this.\r\n    * We can take neither.\r\n    * We can take the backwards-compatible stuff, forget the strict `this` checking.\r\n    * We can take both, and give people a heads up that there's going to be a perf hit for strict `this` checking. \r\n\r\n## No implicit `this`\r\n\r\n* Should we have that?\r\n    * Yes!\r\n* Should it be part of `noImplicitAny`?\r\n    * Well that breaks code.\r\n    * You'd need a suppressing flag.\r\n    * Nobody likes that, so `noImplicitThis` would not be umbrella'd.\r\n\r\n# Library modularization (#6974)\r\n\r\n* Background: hard to say what environments will have what at runtime.\r\n  Our libraries try to be all-encompassing.\r\n\r\n  The workaround has been to modify `lib.d.ts` on your own, but nobody wants to do that.\r\n\r\n* Current solution: granular libraries.\r\n* What about ambient decorators?\r\n    * Let's come back to that.\r\n* You have `es6.array.d.ts`, `es6.collection.d.ts`, etc.\r\n* New `--lib` flag, takes a list of options.\r\n    * You can still just specify `es6` as the lib as an aggregate flag (include `es6.*.d.ts`).\r\n    * Also have an `es7.d.ts` for all one functions that were added to ES7.\r\n    * `--target` toggles the default if `--lib` isn't specified.\r\n        * `--target es2015` still includes `lib.es6.d.ts`.\r\n    * What about ES2015? ES6 technically doesn't exist.\r\n        * Everyone hates the official name.\r\n        * We have no choice. ¯\\\\\\_(ツ)\\_/¯\r\n* So by default, you get the ES3 lib?\r\n    * Sort of. It's more like ES5.5. We haven't split out the ES3/ES5 stuff.\r\n        * Why?\r\n        * Backwards compatibility.\r\n    * So due to back-compat, is DOM always in `lib.d.ts`?\r\n        * Yes?\r\n        * But you can just use `--lib es5` and add from there on.\r\n            * To add to that, you make it `--lib es5,dom`.\r\n        * But we could always add `--lib node`.\r\n* What about granular transformations?\r\n    * People want `async/await` because Node has it, but as soon as you try to do ES6 emit, you run into problems like Node not supporting destructuring.\r\n    * That's the next step.\r\n\r\n## Conditional compilation stuff\r\n\r\n* We're not fully committed to this.\r\n\r\n## Granularity\r\n\r\n* The granularity is great.\r\n    * But there are some clear defaults.\r\n    * Are there situations where people need *all* this granularity?\r\n    * Can overwhelm users, can become a maintenance headache.\r\n    * Let's keep these split up, not commit to them just yet.\r\n\r\n# Control Flow Analysis For Everything (#2388)\r\n\r\n* Background:\r\n    * We needed reachability analysis.\r\n    * Now we need control flow-based type analysis.\r\n* Now, we've subsumed reachability analysis with our work on control flow-based type analysis.\r\n* We now track all assignments and type-guards.\r\n    * Assignments are now considered type-guards themselves as well.\r\n\r\nConsider\r\n\r\n```ts\r\nfunction countLines(text: string[]) {\r\n    let count: number;\r\n    for (const line of text) {\r\n        if (line.length !== 0) {\r\n            count = count + 1;\r\n        }\r\n    }\r\n    return count;\r\n}\r\n```\r\n\r\n* Our new checks will now yell at you for forgetting to initialize `count` and not informing us that `count` could be `undefined`.\r\n* Even if you initialize it at the wrong point.\r\n\r\n  ```ts\r\n  function countLines(text: string[]) {\r\n      let count: number;\r\n      for (const line of text) {\r\n          count = 0; // not good enough - this loop might never execute!\r\n          if (line.length !== 0) {\r\n              count = count + 1;\r\n          }\r\n      }\r\n      return count;\r\n  }\r\n  ```\r\n* We also infer correctly from falling through.\r\n\r\n  ```ts\r\n  function countLines(text: string[]) {\r\n      if (text) {\r\n        let count: number = 0;\r\n        for (const line of text) {\r\n            if (line.length !== 0) {\r\n                count = count + 1;\r\n            }\r\n        }\r\n        return count;\r\n      }\r\n  }\r\n  ```\r\n    * `countLines` has type `number | undefined` since you implicitly returned `undefined`.\r\n\r\n## Assignments as a new type guard point\r\n\r\n```ts\r\ndeclare function getNumberOrString(): number | string;\r\n\r\nvar x = getNumberOrString(); // has type 'number | string'\r\n\r\nif (typeof x === \"string\") {\r\n    x;          // has type 'string'\r\n    \r\n    x = 1000;   // still okay to assign a 'number'\r\n    \r\n    x;          // has type 'number'\r\n}\r\n```\r\n\r\n## Shortcomings\r\n\r\n### Array accesses\r\n\r\nTechnically we should be introducing `undefined` from array indexing, but this would be such a massive pain for users that we can't consider this path.\r\n\r\n## Variable capture in closures \r\n\r\nWe don't track usage of a variable's use within a function.\r\n\r\n```ts\r\nfunction uh_oh() {\r\n    return s.slice();\r\n}\r\nvar s: string;\r\nuh_oh(); // no error.\r\n```\r\n\r\n## Potential for other work\r\n\r\n* Could we use this logic for checking for `this` before `super`, etc.?\r\n    * Yes!"}}