Skip to content

Comments

refactor(compiler-cli): Add report readonly signals in two-way bindings#67199

Open
SkyZeroZx wants to merge 1 commit intoangular:mainfrom
SkyZeroZx:refactor/add-report-readonly-signal
Open

refactor(compiler-cli): Add report readonly signals in two-way bindings#67199
SkyZeroZx wants to merge 1 commit intoangular:mainfrom
SkyZeroZx:refactor/add-report-readonly-signal

Conversation

@SkyZeroZx
Copy link
Contributor

@SkyZeroZx SkyZeroZx commented Feb 22, 2026

Adds a diagnostic error when a read-only signal is used in a two-way binding.

Fixes #67188

What is the current behavior?

@Directive({
  selector: '[stringModel]',
})
export class StringModel {
  myModel = model.required<string>();
}

@Directive({
  selector: '[anyModel]',
})
export class AnyModel {
  // The 'any' or 'unknown' type here suppresses the check for WritableSignal requirements
  anyModel = model.required<unknown>();
}

@Component({
  selector: 'app-root',
  imports: [FormsModule,  AnyModel],
  template: `
    <input [(ngModel)]="value" name="ngModel" /> 
    <input [(anyModel)]="value" name="anyModel" />
   <!-- or --!>
     @let letRefComputed = computedValue; // Similar for Signal , InputSignal 
    <input [(anyModel)]="letRefComputed" name="anyModel" />
  `,
})
export class Main {
  value = signal(1).asReadonly();
  computedValue= computed(()=> value() + 1 )
}

What is the new behavior?

Now throw exception like

Cannot use read-only signal 'value' in a two-way binding expression. Two-way bindings require a `WritableSignal`.

Adds a diagnostic error when a read-only signal is used in a two-way binding.

Fixes angular#67188
@pullapprove pullapprove bot requested a review from devversion February 22, 2026 23:48
@angular-robot angular-robot bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Feb 22, 2026
@ngbot ngbot bot added this to the Backlog milestone Feb 22, 2026
@Component({
template: \`
@let templateComputed = computedValue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m wondering whether should be here or in the @let type check , i think should be there, since it’s for two-way binding

Comment on lines +392 to +395
expect(diags[2].messageText).toBe(
`Cannot use read-only signal 'value' in a two-way binding expression. Two-way bindings require a \`WritableSignal\`.`,
);
});
Copy link
Member

@JeanMeche JeanMeche Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're adding an unecessary diagnostic here.
Should we only send it when we have an any type on the 2 way binding ? (because the typechecking system is able to catch the mismatch in the other cases).

@JeanMeche
Copy link
Member

JeanMeche commented Feb 23, 2026

Also this change is breaking in G3:

foobar: Signal<string>

constructor() {
    foobar = linkedSignal(() => ...); 
}

Which is probably a true positive, since is way binded to an any input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: compiler Issues related to `ngc`, Angular's template compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Template check does not fail for ngModel and readonly Signals

2 participants