From 5cecd97493025cd940c9ade4ea9f1836d5b05cc8 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 16 Dec 2019 21:47:37 +0100 Subject: [PATCH] feat(forms): expand NgModel disabled type to work with strict template 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 ``` 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 --- packages/forms/src/directives/ng_model.ts | 10 ++++++++++ tools/public_api_guard/forms/forms.d.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/packages/forms/src/directives/ng_model.ts b/packages/forms/src/directives/ng_model.ts index b4e252a9cb..1a91885f27 100644 --- a/packages/forms/src/directives/ng_model.ts +++ b/packages/forms/src/directives/ng_model.ts @@ -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; diff --git a/tools/public_api_guard/forms/forms.d.ts b/tools/public_api_guard/forms/forms.d.ts index 756a1654d4..4780d5b0f7 100644 --- a/tools/public_api_guard/forms/forms.d.ts +++ b/tools/public_api_guard/forms/forms.d.ts @@ -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 {