We extract the identifier name from the `foreignImports` expression in
`ComponentDecoratorHandler` and use a `SelectorlessMatcher` to match element
tags against these names. If an element matches both a regular Angular
directive and a foreign component, a conflict error is thrown.
In addition, we implement strict template semantic validation for these matched
foreign components within `TemplateSemanticsChecker`. Elements matched as
foreign components only support static attributes and property bindings. Any
event bindings, template references, or non-property input bindings (e.g.
class, style, or attribute bindings) trigger a semantic error diagnostic.
Finally, we skip standard DOM schema checks for foreign components to prevent spurious
validation errors since foreign components are not defined in standard HTML schemas.
PR Close#68674
- Added the ForeignComponent interface in @angular/core.
- Added Component.foreignImports for importing ForeignComponents (supporting direct references and adapter function wrappers).
- Updated the compiler to handle ForeignComponent in template dependencies.
- Updated ngtsc to extract foreignImports from standalone components.
Currently if a `@for` loop doesn't have a `track` expression we don't produce an AST for it at all which means no type checking and language service support for it.
These changes make it so we produce the AST anyways since it gives the user more tools to resolve the issue (e.g. autocompletion when writing the `track` expression).
The `readFileBuffer` method in `node_js_file_system.ts` was wrapped in
`@ts-ignore` to suppress a TS2322 Buffer/Uint8Array typing error that
was fixed in the TypeScript 5.9.2 upgrade. The minimum supported
TypeScript is now 6.0, so the suppression is dead.
Convert four `.forEach()` calls in `private_export_checker.ts` and
`reference_graph.ts` to `for...of`, matching the iteration style used
elsewhere in the compiler. The TODOs that forced these workarounds are
obsolete.
The getters and setters for jsDocParsingMode in `host.ts` and
`ts_create_program_driver.ts` were suppressed with @ts-ignore to
support TypeScript 5.2, which lacked the property on `ts.CompilerHost`.
The minimum supported TypeScript is now 6.0, and `jsDocParsingMode`
is part of the public TypeScript API, so the suppressions can go.
This allows us to show the API docs when the jsdoc block is at the top of a overloaded function (and not on the implementation signature).
eg: `injectAsync`
Ensure paths are normalized before comparison and key generation in tcb_adapter.ts to avoid failures on Windows.
Ensure a newline before appending imports in TypeCheckFile.render to prevent trailing comments from neutralizing them.
PR Close#68454
This change updates the language service to generate TCBs for templates that would previously
have required inlining. The new strategy is to copy the original source and then do inlining
in the external TCB. This allows language features and type-checking in templates of non-exported
classes (such as test components) or classes with local, non exported dependencies.
PR Close#68454
Langauge service previously never compiled non-exported classes. This avoided issues
where test modules would cause diagnostic noise due to components appearing in
declarations of two modules, for example. This change updates the logic to ensure
non-exported, but standalone classes _are_ still compiled.
fixes#65515
PR Close#68454
Moves the event attribute validation check outside of `ngDevMode` in the `elementAttributeInternal` instruction to ensure that bindings to event attributes like `on*` are always blocked at runtime.
Rather than requiring TS AST in the indexer API, this update makes it generic with adapters to provide necessary information. This allows other analysis pipelines that don't use TS AST to work with the indexer.
This change adds a new that allows environments that cannot support inline TCBs (such as the language service or source-to-source transforms where TS compilation and emit are downstream) to still perform template type checking.
Instead of inlining the TCB into the original source file when non-exported symbols are referenced, we now copy the file content to the .ngtypecheck.ts shim file and generate the external TCB there, if requested by the inlining mode. This preserves the local scope of the original file while keeping the original file unmodified.
all necessary info is already available in the tcb meta objects. environments without full ts program no longer need a reflectionhost for tcb generation
Removes the `checkTwoWayBoundEvents` flag since the code it generates is quite breaking and we never got the chance to enable it. Also it caused our tests to misrepresent how the compiler behaves for actual users.
These changes introduce the new `@Service` decorator which is a more ergonomic alternative to `@Injectable`. The reason we're adding a new decorator is that `@Injectable` has been around since the beginning of Angular and it has a lot of baggage that adds unnecessary overhead for users that generally want to define a singleton service, available in their entire app. The key differences between `@Service` and `@Injectable` are:
1. `@Service` is `providedIn: 'root'` by default. You can opt into providing the service yourself by setting `autoProvided: false` on it.
2. `@Service` doesn't allow constructor-based injection, only the `inject` function.
3. `@Service` doesn't support the complex type signature of `@Injectable` (`useClass`, `useValue` etc.). Instead it supports a single `factory` function.
Example:
```ts
import {Service} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {AuthService} from './auth';
@Service()
export class PostService {
private readonly httpClient = inject(HttpClient);
private readonly authService = inject(AuthService);
getUserPosts() {
return this.httpClient.get('/api/posts/' + this.authService.userId);
}
}
```
Moves the logic for generating type check blocks into the compiler since it isn't coupled to TypeScript anymore.
Note: the tests haven't been moved over, because they depend on the environment that's currently in `compiler-cli` and it still has some dependencies on TypeScript.
To support the need to resolve symbols without full AST access (e.g. when using virtual files), this commit decouples `ReferenceSymbol` from `ts.ClassDeclaration`.
Changes:
- Updated `ReferenceSymbol.target` to use `SymbolReference` instead of `ts.ClassDeclaration`.
- Removed `getReferenceTargetNode()` from `SymbolDirectiveMeta` and transitioned to `getSymbolReference()`.
- Refactored `getTsSymbolOfReference` in `checker.ts` to handle `SymbolReference` and resolve it to a `ts.Symbol` using a position-optimized AST traversal. This avoids using the private `getTokenAtPosition` API and avoids full file scans by only traversing nodes containing the target position.
The commit updates the TCB for safe navigation expressions to allow for correct narrowing of nullables.
This will trigger the `nullishCoalescingNotNullable` and `optionalChainNotNullable` diagnostics on exisiting projects.
You might want to disable those 2 diagnotiscs in your `tsconfig` temporarily if you want to update your project without having to fix all the issues at once.
Narrowing can be disabled altogether with `strictSafeNavigationTyes: false`.
fixes#37619
BREAKING CHANGE: This change will trigger the `nullishCoalescingNotNullable` and `optionalChainNotNullable` diagnostics on exisiting projects.
You might want to disable those 2 diagnotiscs in your `tsconfig` temporarily.
Decouple `SymbolBuilder` from the full `BoundTarget` interface by introducing a purpose-built `SymbolBoundTarget` interface containing only the 4 methods required for symbol resolution. This eliminates the need for the large, pass-through `BoundTargetAdapter` and further isolates `SymbolBuilder` from compiler-internal implementation details.
Also minimize `TypeCheckableDirectiveMetaAdapter` by redefining `SymbolDirectiveMeta` to not extend `DirectiveMeta`, exposing only the properties actually used by `SymbolBuilder`.
Removed dead code `getDirectiveMeta` in `template_symbol_builder.ts` which was unused.
These changes improve maintainability and ensure a cleaner architecture by strictly defining the boundaries of what `SymbolBuilder` needs from the rest of the system.
By limiting the required inputs to only what's necessary for the implementation, we make it easier to re-use
the implementation between different compiler architectures
removing ts.typechecker in a prior refactor caused some regressions, particularly when multiple directives
appear on a single elemnt. this is now addressed by using an id for directives and storing that in the tcb comment
Fixes an error that was heppning when a generic param has type parameters of its own. There were a few different issues going on:
1. In #67707 I had changed a bit how we pass the `genericContextBehavior` which ended up ignoring the `useContextGenericType` option from the environment.
2. All directives depend on themselves, but we were overridding the `genericContextBehavior` for the directive being processed.
3. The type translator wasn't handling type parameter declarations. Technically we shouldn't be able to hit a code path that has a type parameter, however it's also easy enough to handle so we might as well.
Relates to #67704.
- Fixes TemplateSymbolBuilder.getTcbPositionForNode to recursively unwrap AsExpression and NonNullExpression nodes.
- Added a test case in type_checker__get_symbol_of_template_node_spec.ts to verify symbol mapping when strictSafeNavigationTypes is false.
- Note: The issue likely broke in commit 13c8df67d9.
This updates the SymbolBuilder to no longer use ts.TypeChecker internally to
build symbols for the language service. These lookups are deferred/done later
using the newly expanded template type checker API.
Implements the logic at the compiler level that will de-duplicate host directives and merge them together. It will also report if a conflict is detected during merging.
Moves the `ClassPropertyMapping` into the compiler, rather than having to pass around the limited `InputOutputPropertySet` interface that is only implemented by `ClassPropertyMapping`.