A Misspelled Output Still Compiles
Angular 22.2 adds a compiler option that fails the build on an event binding nobody claims. It is off by default.
I used to have (valueChnage) in a template.
Not valueChange. A binding for an event nobody fires.
What the compiler does with a name it does not know
You write (valueChange)="save()" on an element. Angular looks for an output called valueChange on the directives on that element. If it finds one, the binding is wired to it.
If it does not, Angular treats the name as a DOM event and attaches a listener. A misspelling lands there. valueChnage is a perfectly valid event name, so the compiler has nothing to object to. The listener is added, and nothing ever fires the event.
The option
Angular 22.2 adds strictUnclaimedEventNames. The change is pull request #70527.
{
"angularCompilerOptions": {
"strictTemplates": true,
"strictUnclaimedEventNames": true
}
}
With it on, a binding on an element with a matched directive is reported when its name matches neither an output of those directives nor a known native event. The error is NG8030 and the build fails.
It is off by default, and strictTemplates does not turn it on. Upgrading breaks nothing until you ask it to.
Why a person does not catch this
A reviewer reading a diff does not see a missing handler. They see a line that looks right. The binding is there, the method is there, the two names are almost the same. There is no warning and no red, and no test fails unless one happens to exercise that exact path.
That is the finished-looking problem from the article on checks in its smallest form. The work looks done and nothing in the build can tell otherwise.
What it does not catch
The pull request calls it a heuristic, and it is one.
Only plain camelCase names are reported, so an all-lowercase misspelling is not. Dash-case names are skipped, because bubbling custom events conventionally use them. An element with no directive on it is out of scope, so a typo on a bare <div> goes through. NO_ERRORS_SCHEMA disables the check entirely, and with CUSTOM_ELEMENTS_SCHEMA an element without a matched component is exempt.
What it costs to turn on
A camelCase custom event on an element that also carries a directive matches no output and no native event, so it is reported. That includes the ones you meant.
On an existing app, expect a list on the first build. Each line is either a real bug or a deliberate event that now has to be renamed to dash-case or left alone with the flag off. Both are worth knowing, and neither is free.
Where it earns its keep
New code is the weaker case. A misspelled output is a typing slip, and templates that are generated rather than typed make fewer of them.
The strong case is the app that already exists. Years of hand-typed bindings, written before anything checked event names, and nobody has read them for this. That is where a valueChnage can still be sitting, and where turning the flag on once will find it.
What I would do
On an existing app, turn it on in a branch and read the list once.
On a new project, turn it on anyway. There is nothing to clean up, so it costs nothing.
valueChnage was a perfectly valid event name. That is the whole problem.

