angular-cn/tools/public_api_guard
JoostK e9ead2bc09 feat(ivy): more accurate type narrowing for `ngIf` directive (#30248)
A structural directive can specify a template guard for an input, such that
the type of that input's binding can be narrowed based on the guard's return
type. Previously, such template guards could only be methods, of which an
invocation would be inserted into the type-check block (TCB). For `NgIf`,
the template guard narrowed the type of its expression to be `NonNullable`
using the following declaration:

```typescript
export declare class NgIf {
  static ngTemplateGuard_ngIf<E>(dir: NgIf, expr: E): expr is NonNullable<E>
}
```

This works fine for usages such as `*ngIf="person"` but starts to introduce
false-positives when e.g. an explicit non-null check like
`*ngIf="person !== null"` is used, as the method invocation in the TCB
would not have the desired effect of narrowing `person` to become
non-nullable:

```typescript
if (NgIf.ngTemplateGuard_ngIf(directive, ctx.person !== null)) {
  // Usages of `ctx.person` within this block would
  // not have been narrowed to be non-nullable.
}
```

This commit introduces a new strategy for template guards to allow for the
binding expression itself to be used as template guard in the TCB. Now,
the TCB generated for `*ngIf="person !== null"` would look as follows:

```typescript
if (ctx.person !== null) {
  // This time `ctx.person` will successfully have
  // been narrowed to be non-nullable.
}
```

This strategy can be activated by declaring the template guard as a
property declaration with `'binding'` as literal return type.

See #30235 for an example where this led to a false positive.

PR Close #30248
2019-05-16 09:48:40 -07:00
..
animations docs: update animations to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
common feat(ivy): more accurate type narrowing for `ngIf` directive (#30248) 2019-05-16 09:48:40 -07:00
core refactor(ivy): migrate ɵɵ prefix back to Δ (#30362) 2019-05-14 16:52:15 -07:00
elements docs: update elements to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
forms feat(forms): clear (remove all) components from a FormArray (#28918) 2019-03-07 19:52:49 -08:00
http docs(http): move examples to `@usageNotes` (#26039) 2018-09-24 09:11:02 -07:00
platform-browser feat: remove deprecated DOCUMENT token from platform-browser (#28117) 2019-04-25 14:40:16 -07:00
platform-browser-dynamic docs: update platform-browser-dynamic to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
platform-server docs: update platform-server to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
platform-webworker docs: update platform-webworker to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
platform-webworker-dynamic docs: update platform-webworker to use `@publicApi` tags (#26595) 2018-10-19 14:35:53 -07:00
router feat(router): deprecate loadChildren:string (#30073) 2019-04-24 17:06:05 -07:00
service-worker refactor(service-worker): DRY up SW registration logic (#21842) 2019-04-25 12:29:58 -07:00
upgrade test: update upgrade golden file (#28642) 2019-02-21 23:56:28 -08:00
BUILD.bazel refactor(upgrade): use Bazel packages to avoid symlinks in the source (#29466) 2019-04-02 10:38:01 -07:00
global_utils.d.ts fix(ivy): Implement remaining methods for DebugNode (#27387) 2018-12-04 19:58:25 -08:00
public_api_guard.bzl build(ivy): remove the remains of ivy-jit mode (#27278) 2018-11-27 10:30:58 -08:00