Go to file
Alex Rickabaugh a61fe4177f fix(ivy): emulate a View Engine type-checking bug with safe navigation (#35462)
In its default compatibility mode, the Ivy template type-checker attempts to
emulate the View Engine default mode as accurately as is possible. This
commit addresses a gap in this compatibility that stems from a View Engine
type-checking bug.

Consider two template expressions:

```html
{{ obj?.field }}
{{ fn()?.field }}
```

and suppose that the type of `obj` and `fn()` are the same - both return
either `null` or an object with a `field` property.

Under View Engine, these type-check differently. The `obj` case will catch
if the object type (when not null) does not have a `field` property, while
the `fn()` case will not. This is due to how View Engine represents safe
navigations:

```typescript
// for the 'obj' case
(obj == null ? null as any : obj.field)

// for the 'fn()' case
let tmp: any;
((tmp = fn()) == null ? null as any : tmp.field)
```

Because View Engine uses the same code generation backend as it does to
produce the runtime code for this expression, it uses a ternary for safe
navigation, with a temporary variable to avoid invoking 'fn()' twice. The
type of this temporary variable is 'any', however, which causes the
`tmp.field` check to be meaningless.

Previously, the Ivy template type-checker in compatibility mode assumed that
`fn()?.field` would always check for the presence of 'field' on the non-null
result of `fn()`. This commit emulates the View Engine bug in Ivy's
compatibility mode, so an 'any' type will be inferred under the same
conditions.

As part of this fix, a new format for safe navigation operations in template
type-checking code is introduced. This is based on the realization that
ternary based narrowing is unnecessary.

For the `fn()` case in strict mode, Ivy now generates:

```typescript
(null as any ? fn()!.field : undefined)
```

This effectively uses the ternary operator as a type "or" operation. The
resulting type will be a union of the type of `fn()!.field` with
`undefined`.

For the `fn()` case in compatibility mode, Ivy now emulates the bug with:

```typescript
(fn() as any).field
```

The cast expression includes the call to `fn()` and allows it to be checked
while still returning a type of `any` from the expression.

For the `obj` case in compatibility mode, Ivy now generates:

```typescript
(obj!.field as any)
```

This cast expression still returns `any` for its type, but will check for
the existence of `field` on the type of `obj!`.

PR Close #35462
2020-02-21 12:36:11 -08:00
.circleci ci: get rid of the `CI_CHROMEDRIVER_VERSION_ARG` env var (#35381) 2020-02-18 12:42:48 -08:00
.devcontainer build: update the recommended `Dockerfile` for VSCode remote development (#34697) 2020-01-09 13:31:14 -08:00
.github ci: Migrate from CODEOWNERS to PullApprove for PR review management (#34814) 2020-01-28 09:19:34 -08:00
.vscode build: migrate references and scripts that set to build with ivy via compile=aot to use config=ivy (#33983) 2019-11-26 16:38:40 -05:00
.yarn build: vendor yarn using the .yarnrc yarn-path value (#34902) 2020-01-23 11:41:23 -08:00
aio feat: support passive event options by defining global variables in zone.js config file (#34503) 2020-02-21 09:06:26 -08:00
docs docs: minor typo fix (#35423) 2020-02-13 10:08:23 -08:00
integration feat: support passive event options by defining global variables in zone.js config file (#34503) 2020-02-21 09:06:26 -08:00
modules refactor(benchpress): delete outdated/unused folder (#35147) 2020-02-07 16:14:27 -08:00
packages fix(ivy): emulate a View Engine type-checking bug with safe navigation (#35462) 2020-02-21 12:36:11 -08:00
scripts build: several minor fixes related to using `puppeteer` (#35381) 2020-02-18 12:42:47 -08:00
third_party ci: Remove old vendoring solution in favor of relying on yarn-path (#35083) 2020-02-06 15:30:51 -08:00
tools build: refactor zone bazel settings (#34532) 2020-02-20 15:20:14 -08:00
.bazelignore build: add integration/platform-server/node_modules to .bazelignore (#33765) 2019-11-22 16:52:08 -05:00
.bazelrc refactor: simplify bazel saucelabs targets using karma pre-test wrapper and shared saucelabs connection between tests (#34769) 2020-01-28 13:47:00 -08:00
.clang-format
.editorconfig build: use https link to editorconfig.org in .editorconfig (#27664) 2018-12-18 09:30:09 -08:00
.gitattributes test: fix ts api guardian and public guard tests on windows (#30105) 2019-04-26 16:32:22 -07:00
.gitignore ci: do not run benchmark measurements in circleci (#34753) 2020-01-29 09:22:27 -08:00
.mailmap
.nvmrc build: migrate to node@12.14.1 (#34955) 2020-01-27 09:31:22 -08:00
.pullapprove.yml ci: update pullapprove config to ensure complete coverage of files (#35060) 2020-02-12 16:39:13 -08:00
.yarnrc build: vendor yarn using the .yarnrc yarn-path value (#34902) 2020-01-23 11:41:23 -08:00
BUILD.bazel refactor: simplify bazel saucelabs targets using karma pre-test wrapper and shared saucelabs connection between tests (#34769) 2020-01-28 13:47:00 -08:00
CHANGELOG.md release: cut the v9.1.0-next.1 release 2020-02-19 12:15:43 -08:00
CODE_OF_CONDUCT.md docs: fix community tab in GitHub by copying CoC 2018-02-27 19:02:30 -08:00
CONTRIBUTING.md docs: document golden file requirement (#33900) 2020-01-07 10:58:53 -08:00
LICENSE build: bump year (#34651) 2020-01-13 07:21:43 -08:00
README.md docs: fix typo of Typescript to TypeScript (#32153) 2019-08-15 12:44:41 -07:00
WORKSPACE build: update to @bazel/bazel 2.1.0 (#35430) 2020-02-13 16:29:32 -08:00
browser-providers.conf.js ci: update the browser test matrix to match supported browsers (#35202) 2020-02-14 11:14:05 -08:00
gulpfile.js build: create bazel marco to test for circular dependencies (#34774) 2020-01-23 11:36:40 -08:00
karma-js.conf.js ci: ensure saucelabs browsers can load karma test page (#35171) 2020-02-06 15:36:27 -08:00
package.json build: update cli packages to latest versions (#35608) 2020-02-21 08:31:18 -08:00
protractor-perf.conf.js test: ensure global options for benchmark tests can be set in bazel (#34753) 2020-01-29 09:22:27 -08:00
shims_for_IE.js
test-events.js refactor: rename unpatched event flag in Zone from `BLACK_LISTED_EVENTS` to `UNPATCHED_EVENTS` (#29617) 2019-10-04 08:44:58 -07:00
test-main.js feat(ivy): i18n - implement compile-time inlining (#32881) 2019-10-09 13:19:38 -07:00
tslint.json style: enforce disallowance of object constructor (#33211) 2019-12-03 10:08:25 -08:00
yarn.lock build: update cli packages to latest versions (#35608) 2020-02-21 08:31:18 -08:00
yarn.lock.readme.md build: remove travisci leftovers (#27979) 2019-01-09 10:41:16 -08:00

README.md

CircleCI BrowserStack Status Join the chat at https://gitter.im/angular/angular npm version

Angular

Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.

Quickstart

Get started in 5 minutes.

Changelog

Learn about the latest improvements.

Want to help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for contributing and then check out one of our issues in the hotlist: community-help.