Skip to content

Commit

Permalink
feat(forms): expand NgModel disabled type to work with strict templat…
Browse files Browse the repository at this point in the history
…e type checking (#34438)

NgModel internally coerces any arbitrary value that will assigned
to the `disabled` `@Input` to a boolean. This has been done to
support the common case where developers set the disabled attribute
without a value. For example:

```html
<input type="checkbox" [(ngModel)]="value" disabled>
```

This worked in View Engine without any errors because inputs were
not strictly checked. In Ivy though, developers can opt-in into
strict template type checking where the attribute would be flagged.

This is because the `NgModel#isDisabled` property type-wise only
accepts a `boolean`. To ensure that the common pattern described
above can still be used, and to reflect the actual runtime behavior,
we should add an acceptance member that makes it work without type
checking errors.

Using a coercion member means that this is not a breaking change.

PR Close #34438
  • Loading branch information
devversion authored and kara committed Dec 16, 2019
1 parent 5df8a3b commit 5cecd97
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/forms/src/directives/ng_model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ const resolvedPromise = (() => Promise.resolve(null))();
export class NgModel extends NgControl implements OnChanges,
OnDestroy {
public readonly control: FormControl = new FormControl();

// At runtime we coerce arbitrary values assigned to the "disabled" input to a "boolean".
// This is not reflected in the type of the property because outside of templates, consumers
// should only deal with booleans. In templates, a string is allowed for convenience and to
// match the native "disabled attribute" semantics which can be observed on input elements.
// This static member tells the compiler that values of type "string" can also be assigned
// to the input in a template.
/** @nodoc */
static ngAcceptInputType_disabled: boolean|string;

/** @internal */
_registered = false;

Expand Down
1 change: 1 addition & 0 deletions tools/public_api_guard/forms/forms.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ export declare class NgModel extends NgControl implements OnChanges, OnDestroy {
ngOnChanges(changes: SimpleChanges): void;
ngOnDestroy(): void;
viewToModelUpdate(newValue: any): void;
static ngAcceptInputType_disabled: boolean | string;
}

export declare class NgModelGroup extends AbstractFormGroupDirective implements OnInit, OnDestroy {
Expand Down

0 comments on commit 5cecd97

Please sign in to comment.