{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/59333517","id":59333517,"diff_hunk":"@@ -1811,7 +1811,7 @@ namespace ts {\n         function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {\r\n             let entity: EntityName = parseIdentifier(diagnosticMessage);\r\n             while (parseOptional(SyntaxKind.DotToken)) {\r\n-                const node = <QualifiedName>createNode(SyntaxKind.QualifiedName, entity.pos);\r\n+                const node: QualifiedName = <QualifiedName>createNode(SyntaxKind.QualifiedName, entity.pos);  // !!!\r","path":"src/compiler/parser.ts","position":5,"original_position":5,"commit_id":"4c250d046f1c2455862a78a3722dfcf7fbbe9e9a","original_commit_id":"4c250d046f1c2455862a78a3722dfcf7fbbe9e9a","user":{"login":"JsonFreeman","id":8052525,"avatar_url":"https://avatars.githubusercontent.com/u/8052525?v=3","gravatar_id":"","url":"https://api.github.com/users/JsonFreeman","html_url":"https://github.com/JsonFreeman","followers_url":"https://api.github.com/users/JsonFreeman/followers","following_url":"https://api.github.com/users/JsonFreeman/following{/other_user}","gists_url":"https://api.github.com/users/JsonFreeman/gists{/gist_id}","starred_url":"https://api.github.com/users/JsonFreeman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JsonFreeman/subscriptions","organizations_url":"https://api.github.com/users/JsonFreeman/orgs","repos_url":"https://api.github.com/users/JsonFreeman/repos","events_url":"https://api.github.com/users/JsonFreeman/events{/privacy}","received_events_url":"https://api.github.com/users/JsonFreeman/received_events","type":"User","site_admin":false},"body":"One other idea is that while doing the analysis, if you hit a type assertion, ignore the RHS, and just use the type associated with the type assertion.","created_at":"2016-04-12T07:46:31Z","updated_at":"2016-04-12T07:46:31Z","html_url":"https://github.com/Microsoft/TypeScript/pull/8010#discussion_r59333517","pull_request_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/59333517"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/8010#discussion_r59333517"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010","id":66027430,"html_url":"https://github.com/Microsoft/TypeScript/pull/8010","diff_url":"https://github.com/Microsoft/TypeScript/pull/8010.diff","patch_url":"https://github.com/Microsoft/TypeScript/pull/8010.patch","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/8010","number":8010,"state":"open","locked":false,"title":"Control flow based type analysis","user":{"login":"ahejlsberg","id":4226954,"avatar_url":"https://avatars.githubusercontent.com/u/4226954?v=3","gravatar_id":"","url":"https://api.github.com/users/ahejlsberg","html_url":"https://github.com/ahejlsberg","followers_url":"https://api.github.com/users/ahejlsberg/followers","following_url":"https://api.github.com/users/ahejlsberg/following{/other_user}","gists_url":"https://api.github.com/users/ahejlsberg/gists{/gist_id}","starred_url":"https://api.github.com/users/ahejlsberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ahejlsberg/subscriptions","organizations_url":"https://api.github.com/users/ahejlsberg/orgs","repos_url":"https://api.github.com/users/ahejlsberg/repos","events_url":"https://api.github.com/users/ahejlsberg/events{/privacy}","received_events_url":"https://api.github.com/users/ahejlsberg/received_events","type":"User","site_admin":false},"body":"This PR introduces *control flow based type analysis* for local variables and parameters as initially suggested in #2388 and prototyped in #6959. Previously, the type analysis performed for type guards was limited to `if` statements and `?:` conditional expressions and didn't include effects of assignments and control flow constructs such as `return` and `break` statements. With this PR, the type checker analyses all possible flows of control in statements and expressions to produce the most specific type possible (the *narrowed type*) at any given location for a local variable or parameter that is declared to have a union type.\r\n\r\nSome examples:\r\n\r\n```typescript\r\nfunction foo(x: string | number | boolean) {\r\n    if (typeof x === \"string\") {\r\n        x; // type of x is string here\r\n        x = 1;\r\n        x; // type of x is number here\r\n    }\r\n    x; // type of x is number | boolean here\r\n}\r\n\r\nfunction bar(x: string | number) {\r\n    if (typeof x === \"number\") {\r\n        return;\r\n    }\r\n    x; // type of x is string here\r\n}\r\n```\r\n\r\nControl flow based type analysis is particuarly relevant in `--strictNullChecks` mode because nullable types are represented using union types:\r\n\r\n```typescript\r\nfunction test(x: string | null) {\r\n    if (x === null) {\r\n        return;\r\n    }\r\n    x; // type of x is string in remainder of function\r\n}\r\n```\r\n\r\nFurthermore, in `--strictNullChecks` mode, control flow based type analysis includes *definite assignment analysis* for local variables of types that don't permit the value `undefined`.\r\n\r\n```typescript\r\nfunction mumble(check: boolean) {\r\n    let x: number; // Type doesn't permit undefined\r\n    x; // Error, x is undefined\r\n    if (check) {\r\n        x = 1;\r\n        x; // Ok\r\n    }\r\n    x; // Error, x is possibly undefined\r\n    x = 2;\r\n    x; // Ok\r\n}\r\n```\r\n\r\nThe narrowed type of a local variable or parameter at a given source code location is computed by starting with the initial type of the variable and then following each possible code path that leads to the given location, narrowing the type of the variable as appropriate based on type guards and assignments.\r\n\r\n* The initial type of local variable is `undefined`.\r\n* The initial type of a parameter is the declared type of the parameter.\r\n* The initial type of an outer local variable or a global variable is the declared type of that variable.\r\n* A type guard narrows the type of a variable in the code path that follows the type guard.\r\n* An assignment (including an initializer in a declaration) of a value of type S to a variable of type T changes the type of that variable to T *narrowed by* S in the code path that follows the assignment.\r\n* When multiple code paths lead to a particular location, the narrowed type of a given variable at that location is the union type of the narrowed types of the variable in those code paths.\r\n\r\nThe type T *narrowed by* S is computed as follows:\r\n\r\n* If T is not a union type, the result is T.\r\n* If T is a union type, the result is the union of each constituent type in T to which S is assignable.\r\n\r\nThanks to @ivogabe for providing inspiration and tests for this PR.\r\n\r\nFixes #2388.","created_at":"2016-04-11T16:59:49Z","updated_at":"2016-04-12T07:46:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e449e50107d69665c4ec90ea6ddc1650ff978430","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010/commits","review_comments_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010/comments","review_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/8010/comments","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/4c250d046f1c2455862a78a3722dfcf7fbbe9e9a","head":{"label":"Microsoft:controlFlowTypes","ref":"controlFlowTypes","sha":"4c250d046f1c2455862a78a3722dfcf7fbbe9e9a","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":20929025,"name":"TypeScript","full_name":"Microsoft/TypeScript","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":false,"url":"https://api.github.com/repos/Microsoft/TypeScript","forks_url":"https://api.github.com/repos/Microsoft/TypeScript/forks","keys_url":"https://api.github.com/repos/Microsoft/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/TypeScript/teams","hooks_url":"https://api.github.com/repos/Microsoft/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/TypeScript/events","assignees_url":"https://api.github.com/repos/Microsoft/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/TypeScript/tags","blobs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/TypeScript/languages","stargazers_url":"https://api.github.com/repos/Microsoft/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/TypeScript/subscription","commits_url":"https://api.github.com/repos/Microsoft/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/TypeScript/merges","archive_url":"https://api.github.com/repos/Microsoft/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/TypeScript/downloads","issues_url":"https://api.github.com/repos/Microsoft/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/TypeScript/releases{/id}","deployments_url":"https://api.github.com/repos/Microsoft/TypeScript/deployments","created_at":"2014-06-17T15:28:39Z","updated_at":"2016-04-12T04:28:46Z","pushed_at":"2016-04-12T04:44:06Z","git_url":"git://github.com/Microsoft/TypeScript.git","ssh_url":"git@github.com:Microsoft/TypeScript.git","clone_url":"https://github.com/Microsoft/TypeScript.git","svn_url":"https://github.com/Microsoft/TypeScript","homepage":"http://www.typescriptlang.org","size":489459,"stargazers_count":10756,"watchers_count":10756,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1342,"mirror_url":null,"open_issues_count":966,"forks":1342,"open_issues":966,"watchers":10756,"default_branch":"master"}},"base":{"label":"Microsoft:master","ref":"master","sha":"d280b1b7bc9f71491619fa61ee3fa99b54b96b26","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":20929025,"name":"TypeScript","full_name":"Microsoft/TypeScript","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":false,"url":"https://api.github.com/repos/Microsoft/TypeScript","forks_url":"https://api.github.com/repos/Microsoft/TypeScript/forks","keys_url":"https://api.github.com/repos/Microsoft/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/TypeScript/teams","hooks_url":"https://api.github.com/repos/Microsoft/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/TypeScript/events","assignees_url":"https://api.github.com/repos/Microsoft/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/TypeScript/tags","blobs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/TypeScript/languages","stargazers_url":"https://api.github.com/repos/Microsoft/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/TypeScript/subscription","commits_url":"https://api.github.com/repos/Microsoft/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/TypeScript/merges","archive_url":"https://api.github.com/repos/Microsoft/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/TypeScript/downloads","issues_url":"https://api.github.com/repos/Microsoft/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/TypeScript/releases{/id}","deployments_url":"https://api.github.com/repos/Microsoft/TypeScript/deployments","created_at":"2014-06-17T15:28:39Z","updated_at":"2016-04-12T04:28:46Z","pushed_at":"2016-04-12T04:44:06Z","git_url":"git://github.com/Microsoft/TypeScript.git","ssh_url":"git@github.com:Microsoft/TypeScript.git","clone_url":"https://github.com/Microsoft/TypeScript.git","svn_url":"https://github.com/Microsoft/TypeScript","homepage":"http://www.typescriptlang.org","size":489459,"stargazers_count":10756,"watchers_count":10756,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1342,"mirror_url":null,"open_issues_count":966,"forks":1342,"open_issues":966,"watchers":10756,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/8010"},"issue":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/8010"},"comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/8010/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/8010/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/TypeScript/statuses/4c250d046f1c2455862a78a3722dfcf7fbbe9e9a"}}}}