A misspelled Angular output can survive code review because the template still looks plausible: (saveClik) differs from (saveClick) by one letter. The new Angular unclaimed event names check, exposed as strictUnclaimedEventNames in Angular 22.2, can turn this class of silent wiring mistake into diagnostic NG8030 during CI.
This guide explains what the check proves, where its deliberate exemptions begin, and how to roll it out without pretending it validates every custom event. The behavior was verified with Angular compiler CLI 22.2.0-rc.0: the valid fixture compiled, while the same fixture with saveClik failed with NG8030. Because that version is a release candidate, pin it only in an evaluation branch until the stable 22.2 release matches your upgrade policy.
Table of Contents
Why Angular unclaimed event names catches silent typos
Angular templates use the same parenthesized syntax for directive outputs and native DOM events. Before this check, an event name that matched neither could be accepted as an event listener. The application built, but the handler never ran because no directive emitted that name and the browser never raised such an event.
<button saveAction (saveClik)="onSave()">Save</button>
The failure is operationally awkward. The button renders, the click itself is valid, and no exception needs to appear. A unit test may catch the missing call, but only if that interaction is covered. A compiler diagnostic moves the feedback to every build and points at the exact binding.
strictUnclaimedEventNames is intentionally separate from strictTemplates. Angular 22.2 keeps it disabled by default, even in projects that already use strict template checking. That makes rollout a conscious compatibility decision rather than a surprise change for applications with unusual event conventions.
Enable strictUnclaimedEventNames deliberately
Add the option to the Angular compiler settings used by the application build. Keep strictTemplates enabled so the project retains the wider template type-checking guarantees.
{
"angularCompilerOptions": {
"strictTemplates": true,
"strictUnclaimedEventNames": true
}
}
Place the option in the configuration actually consumed by CI. In a workspace with several applications or test targets, inspect the relevant tsconfig.app.json inheritance chain instead of assuming the root tsconfig.json controls every compilation.
Do not enable the flag and immediately suppress all new diagnostics. First classify each failure as a misspelled output, a misspelled native event, or an intentional custom-event pattern covered by one of Angular’s exemptions. That classification is the value of the rollout.
Reproduce NG8030 with a real directive output
The smallest useful proof contains a directive with a declared output and a standalone component that imports it. The directive exposes saveClick:
import { Directive, EventEmitter, Output } from '@angular/core';
@Directive({
selector: '[saveAction]',
standalone: true,
})
export class SaveActionDirective {
@Output() readonly saveClick = new EventEmitter<void>();
}
The valid template binds to that exact name:
@Component({
selector: 'app-root',
standalone: true,
imports: [SaveActionDirective],
template: '<button saveAction (saveClick)="onSave()">Save</button>',
})
export class AppComponent {
onSave(): void {}
}
Change only the binding to saveClik. With the new option enabled, the Angular compiler rejects the template with NG8030 because the element has a matched directive, but the camelCase event name is neither one of its outputs nor a known native DOM event.
template: '<button saveAction (saveClik)="onSave()">Save</button>'
A trustworthy regression fixture should test both sides: the correctly spelled version must compile, and the misspelled version must fail for the expected diagnostic and event name. Merely asserting a nonzero exit code is too weak because an unrelated TypeScript or configuration error could make the negative test pass.
Put the check in CI
Use the normal production compilation rather than a separate lightweight command that bypasses Angular template checking. This makes the Angular unclaimed event names result part of the same build gate that protects deployment. A minimal GitHub Actions job can pin Node, install the lock file, and run the same build command used before deployment:
jobs:
angular-template-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build -- --configuration production
For the focused compiler fixture, the verified command is npm run check. It first compiles the valid component, then launches the invalid compilation and inspects its output for both NG8030 and saveClik. Keep that negative test separate from the application build so an expected failure is never confused with a green production build.
Pin the release-candidate packages and lock file in the experiment. When the stable Angular 22.2 packages arrive, update the fixture and application together, rerun the positive and negative cases, and record the exact compiler version in the pull request.
Understand the intentional exemptions
The implementation is a targeted typo detector, not a closed-world declaration system for every event. Angular deliberately limits the check to single-identifier camelCase names. The following boundaries matter during review:
- Dash-separated custom events are exempt. Names such as
value-changedare not rejected by this rule. - Known native DOM events are allowed. Their comparison is case-insensitive, so this flag is not a general casing style rule.
- Key pseudo-events and targeted events are exempt. Angular’s event syntax supports forms that do not map to a simple output name.
- Schema choices affect coverage. An element accepted through
CUSTOM_ELEMENTS_SCHEMAwithout a matched Angular component is outside this directive-output check, whileNO_ERRORS_SCHEMAdisables the validation. - A matched directive is significant. The compiler uses the directives on the element when deciding whether a camelCase event name is claimed.
These exemptions prevent the option from breaking legitimate web-component and event-plugin patterns. They also explain why the check must complement interaction tests rather than replace them.
Roll out without weakening template safety
Start with one application or library target and run the full compilation locally. Fix obvious spelling mistakes first. If a diagnostic identifies an intentional output, prefer declaring or importing the owning directive correctly over adding a broad schema.
Avoid NO_ERRORS_SCHEMA as an escape hatch. It removes this signal together with other useful template diagnostics. If the application hosts standards-based custom elements, use the narrower CUSTOM_ELEMENTS_SCHEMA only where that integration requires it, and cover those custom events with component tests.
For a monorepo, roll out target by target. Add a temporary CI matrix that compiles each Angular project with its real inherited configuration. Record exceptions by project and reason; do not hide them behind one workspace-wide skip. Once all targets pass, make the option part of the shared base configuration.
Production checklist
- Confirm the compiler version that introduced the behavior; the verified fixture uses
22.2.0-rc.0. - Enable both
strictTemplatesandstrictUnclaimedEventNamesin the configuration consumed by CI. - Compile a known-good output binding and verify that it remains green.
- Compile a one-character typo and require
NG8030plus the event name in the negative fixture. - Review dash-separated events, schemas, web components, key pseudo-events, and targeted events as explicit coverage boundaries.
- Keep browser or component interaction tests for behavior the compiler cannot prove.
- Re-run the fixture when moving from the release candidate to the stable Angular 22.2 packages.
The practical win from Angular unclaimed event names validation is narrow but valuable: a real directive output typo becomes a deterministic compiler failure before the application reaches a reviewer, a test browser, or production.
References
- Angular 22.2.0-rc.0 release
- Angular compiler implementation for strict unclaimed event names
- Commit-pinned Angular template type-checking documentation
Demo
Run the complete verified demo from GitHub.
Found this useful? Support more practical developer content.