From c819880b91bf5ff1c5aa71afd314ae7cae241065 Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Sun, 16 Aug 2026 12:26:25 +0200 Subject: [PATCH] fix(forms): report forbidden 2way bindings on when `FormField` is applied We were already reporting regular bindings but not 2way. fixes #70219 --- .../src/ngtsc/typecheck/src/oob.ts | 2 ++ .../test/ngtsc/signal_forms_spec.ts | 25 +++++++++++++++++++ .../src/typecheck/ops/signal_forms.ts | 2 ++ 3 files changed, 29 insertions(+) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts index 88360173b93..d06e1fea9ab 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts @@ -625,6 +625,8 @@ export class OutOfBandDiagnosticRecorderImpl implements OutOfBandDiagnosticRecor name = `[${node.name}]`; } else if (node.type === BindingType.Attribute) { name = `[attr.${node.name}]`; + } else if (node.type === BindingType.TwoWay) { + name = `[(${node.name})]`; } else { // We shouldn't hit this, but we have this logic as a fallback. name = node.name; diff --git a/packages/compiler-cli/test/ngtsc/signal_forms_spec.ts b/packages/compiler-cli/test/ngtsc/signal_forms_spec.ts index c7f2d3c12f3..0b86c0be83b 100644 --- a/packages/compiler-cli/test/ngtsc/signal_forms_spec.ts +++ b/packages/compiler-cli/test/ngtsc/signal_forms_spec.ts @@ -480,6 +480,31 @@ runInEachFileSystem(() => { ); }); + it('should report unsupported two-way bindings on a field', () => { + env.write( + 'test.ts', + ` + import {Component, signal} from '@angular/core'; + import {FormField, form} from '@angular/forms/signals'; + + @Component({ + template: '', + imports: [FormField] + }) + export class Comp { + f = form(signal('')); + maxLength = 10; + } + `, + ); + + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(1); + expect(extractMessage(diags[0])).toBe( + `Binding to '[(max)]' is not allowed on nodes using the '[formField]' directive`, + ); + }); + it('should report unsupported property bindings on a field with a custom control', () => { env.write( 'test.ts', diff --git a/packages/compiler/src/typecheck/ops/signal_forms.ts b/packages/compiler/src/typecheck/ops/signal_forms.ts index 610816c5121..39ce12f8ba3 100644 --- a/packages/compiler/src/typecheck/ops/signal_forms.ts +++ b/packages/compiler/src/typecheck/ops/signal_forms.ts @@ -429,6 +429,8 @@ export function checkUnsupportedFieldBindings( unsupportedBindingFields.has(input.name.toLowerCase()) ) { tcb.oobRecorder.formFieldUnsupportedBinding(tcb.id, input); + } else if (input.type === BindingType.TwoWay && unsupportedBindingFields.has(input.name)) { + tcb.oobRecorder.formFieldUnsupportedBinding(tcb.id, input); } }