With strictTemplates enabled in Angular, how do flags like strictInputTypes, strictNullInputTypes and strictAttributeTypes relax specific checks?
answer
- one switch per kind of check
- each inherits the strictTemplates value
- turn off one, keep the rest
- two flags stay off by default
basics
~20 sEach Angular strictness flag defaults to the value of strictTemplates and can be set on its own in angularCompilerOptions. Setting one to false disables only that check, such as strictNullInputTypes: false ignoring null mismatches on inputs, while the rest of strict mode stays on.
solid answer
~40 s`strictTemplates` is an umbrella: it switches on a family of **strictness flags**, and any flag you set explicitly overrides it. `strictInputTypes` checks that a binding is assignable to its input (and also drives generic inference and template context guards). `strictNullInputTypes` applies `strictNullChecks` to those input bindings; turning it off is the documented workaround for a library compiled without null checks. `strictAttributeTypes` checks inputs set from plain text attributes, such as `<submit-button disabled>`, which passes an empty string. Others cover `$event` (`strictOutputEventTypes`, `strictDomEventTypes`), `#ref` types (`strictDomLocalRefTypes`), `?.` results (`strictSafeNavigationTypes`) and generics (`strictContextGenerics`). Two stay off even in strict mode unless set explicitly: `strictInputAccessModifiers` and `strictUnclaimedEventNames`. The guidance is to relax the narrowest flag instead of turning strict mode off.
code
json · 7 lines{
"angularCompilerOptions": {
"strictTemplates": true,
"strictNullInputTypes": false,
"strictInputAccessModifiers": true
}
}go deeper
Know that strict mode is made of several switches and that you can turn off one of them in tsconfig instead of all of them.
Name the main flags, what each checks, and the two exceptions that stay off by default, strictInputAccessModifiers and strictUnclaimedEventNames.
Pick the narrowest fix for a false positive: a transform or typed ref first, then one flag, and explain side effects such as losing context guards.
Set a codebase policy for which strictness flags may be relaxed, and require a documented reason, so exceptions do not quietly erode checking.
## An umbrella with individual switches Strict template checking is not one check but a bundle of them. `strictTemplates: true` sets each **strictness flag** to `true`; `strictTemplates: false` sets them to `false`. Any flag you write explicitly in `angularCompilerOptions` wins over the umbrella, in either direction. That lets a team keep strict mode on and switch off only the part that is producing false positives. ## The flags | Flag | What it checks when `true` | | :-- | :-- | | `strictInputTypes` | A binding expression is assignable to its `input()` / `@Input()`; also enables generic inference and template context guards | | `strictNullInputTypes` | `strictNullChecks` is honoured for those input bindings | | `strictAttributeTypes` | Inputs set through plain text attributes (`disabled="true"`) are type-checked | | `strictSafeNavigationTypes` | `user?.name` gets a real type instead of `any` | | `strictDomLocalRefTypes` | `<input #ref>` gives `ref` the element's type | | `strictOutputEventTypes` | `$event` is typed for component outputs and animation events | | `strictDomEventTypes` | `$event` is typed for native DOM events | | `strictContextGenerics` | Generic components get inferred type parameters instead of `any` | | `strictLiteralTypes` | Object and array literals in templates are typed | | `strictInputAccessModifiers` | `private` / `protected` / `readonly` inputs cannot be bound; **`false` by default even in strict mode** | | `strictUnclaimedEventNames` | Reports event bindings that match no output or known DOM event; **`false` by default even in strict mode** | New workspaces generated with the default `--strict` setting also write `"strictInputAccessModifiers": true`, so a fresh project honours access modifiers even though the compiler default is `false`. ## Typical reasons to relax one flag 1. **A library compiled without `strictNullChecks`.** Its declaration files omit `null`, so passing a nullable value fails even though the library handles it. The documented workaround is `strictNullInputTypes: false`, which affects only input bindings and only null-ness. 2. **Boolean attributes.** `<submit-button disabled>` sets the input to `''`. With `strictAttributeTypes` on, an input typed `boolean` rejects it. The modern fix is on the component side: declare the input with a transform, `disabled = input(false, { transform: booleanAttribute })`, so it accepts attribute strings. The older `static ngAcceptInputType_disabled` field is deprecated. 3. **DOM event targets.** `$event.target` is typed as the generic `EventTarget`, because events bubble, so `$event.target.value` fails under `strictDomEventTypes`. Prefer passing a typed local reference (`#box` then `box.value`) over disabling the flag. ## A sensible order of escape hatches Angular's own troubleshooting guidance runs from narrow to broad: - fix the types, or use `$any()` / `!` on the single expression; - set **one** strictness flag to `false`; - as a last resort, disable `strictTemplates`. Older guides describe falling back to an intermediate "full" mode via `fullTemplateTypeCheck`, but the Angular 22.2 compiler no longer reads that flag, so this drops to basic checking and loses checks inside embedded views. An error that can only be avoided this way is likely a type-checker bug worth reporting. ## A worked example A shared `<app-toggle>` declares `disabled = input(false)`. A consumer writes `<app-toggle disabled>`. Under strict mode the build fails: the attribute sets the input to the string `''`, and `strictAttributeTypes` checks that string against `boolean`. There are three responses, from best to worst: 1. **Fix the component**: `disabled = input(false, { transform: booleanAttribute })`, importing `booleanAttribute` from `@angular/core`. The template checker accepts whatever the transform's parameter accepts, and the component always sees a boolean. 2. **Fix the call site**: write `[disabled]="true"` so a real boolean is bound. 3. **Relax the flag**: `strictAttributeTypes: false`. This hides the problem for every attribute-set input in the app. The DOM-event variant follows the same logic. `(input)="save($event.target.value)"` fails under `strictDomEventTypes` because `target` is an `EventTarget`. Writing `<input #box (input)="save(box.value)">` uses a correctly typed local reference and keeps the flag on. ## How the flags interact - `strictNullInputTypes` only matters when TypeScript's `strictNullChecks` is on; without it there is no null distinction to honour. - Setting `strictInputTypes: false` also turns off **template context guards**, so custom structural directives lose their typed contexts. - Flags apply to the whole compilation: there is no per-component override, which is why the narrowest flag matters.
- Why is setting strictInputTypes to false in Angular a bigger change than it looks?Besides stopping input assignability checks, it disables template context guards and weakens generic inference, because the compiler ties those to the same setting. Custom structural directives that declare `ngTemplateContextGuard` would then give `any` to their template variables. Relaxing `strictNullInputTypes` or fixing the types is usually the better move.
- How does an Angular input accept an empty-string attribute such as <app-toggle disabled> under strict attribute checking?Declare it with a transform: `disabled = input(false, { transform: booleanAttribute })`. The template type checker then accepts whatever the transform's parameter accepts, and the component always sees a boolean. The older `ngAcceptInputType_` static field did the same for decorator inputs and is deprecated.
saying these in an interview costs you the question
- Individual strictness flags only work when strictTemplates is false.
- strictInputAccessModifiers is turned on automatically by strictTemplates.
- strictNullInputTypes makes Angular convert null inputs to undefined at runtime.
- Flags can be overridden per component with an option in @Component.
- The only way to silence a false positive is to disable strictTemplates entirely.