-
Notifications
You must be signed in to change notification settings - Fork 10
Description
I think it would be good to add a section outlining known limitations of Angular typing. You can't type everything.
Here are a few limitations (there are likely some more):
Angular templates are not fully type-checked like TypeScript code.
Example:
html
{{ user.name.toUpperCase() }}
If user is null or undefined, this will throw a runtime error, even if TypeScript types suggest user is always defined.
Why it's unavoidable: Templates are interpreted at runtime, and Angular's template type checking is limited compared to TypeScript's compiler.
This issue can be further expanded as I think there are issues with nested signal properties.
🔄 2. Dynamic Forms (Reactive Forms)
Form controls are often created dynamically, and their types are not strictly enforced.
Example:
ts
const form = new FormGroup({
age: new FormControl('')
});
const age: number = form.value.age; // No compile-time error, but age is actually a string
Why it's unavoidable: form.value returns a generic object (any), and Angular doesn't infer types from form definitions.
🌐 3. HTTP Responses
Angular's HttpClient returns Observable unless you explicitly type it. Even then, the type is not enforced at runtime.
Example:
ts
this.http.get<User[]>('/api/users').subscribe(users => {
console.log(users[0].email); // Might be undefined if API response doesn't match
});
Why it's unavoidable: TypeScript types are erased at runtime, and you can't guarantee the backend will return what you expect.
🧩 4. Third-Party Libraries
Using third-party Angular modules or JavaScript libraries often involves any types or loosely typed APIs.
Example:
ts
import * as moment from 'moment';
const date = moment().format(); // Returns string, but no strict typing on format
Why it's unavoidable: Many libraries are not written in TypeScript or have incomplete type definitions.
You can give an example how NPM has a colored TS symbol when a third party library includes typescript types vs having to install a separate package.
🌀 5. Dependency Injection Tokens
Custom injection tokens can be typed, but Angular's DI system doesn't enforce them strictly.
Example:
ts
const MY_TOKEN = new InjectionToken('MyToken');
If you accidentally provide a number instead of a string, Angular won't catch it at compile time.
Why it's unavoidable: DI is resolved at runtime, and type mismatches can slip through.
- Esbuild and Web Worker Type Safety:
Issue:
When using esbuild as the bundler (e.g., in Angular CLI 18+), web workers may not undergo proper build-time type checking, despite the generation of tsconfig.worker.json.
Impact:
Creates a false sense of security, as type errors in web workers might only be discovered at runtime.
This is from the Angular docs:
Type-checking of Web Worker code and processing of nested Web Workers
Web Workers can be used within application code using the same syntax (new Worker(new URL('', import.meta.url))) that is supported with the browser builder. However, the code within the Worker will not currently be type-checked by the TypeScript compiler. TypeScript code is supported just not type-checked. Additionally, any nested workers will not be processed by the build system. A nested worker is a Worker instantiation within another Worker file.
- Dependency Injection Provider deps Mismatches:
Issue:
In class providers with dependency injection, a mismatch between the injected services in the class constructor and the deps array in the provider definition might not be caught at compile or runtime.
Impact:
Can lead to subtle bugs where the wrong service is injected without any immediate error indication.