@@ -38,6 +38,7 @@ use crate::directive::{
3838 extract_content_queries, extract_directive_metadata, extract_view_queries,
3939 find_directive_decorator_span, generate_directive_definitions,
4040} ;
41+ use crate :: dts;
4142use crate :: injectable:: {
4243 extract_injectable_metadata, find_injectable_decorator_span,
4344 generate_injectable_definition_from_decorator,
@@ -276,6 +277,20 @@ pub struct TransformResult {
276277
277278 /// Number of components found in the file.
278279 pub component_count : usize ,
280+
281+ /// `.d.ts` type declarations for Angular classes.
282+ ///
283+ /// Each entry contains the class name and the static member declarations
284+ /// that should be injected into the corresponding `.d.ts` class body.
285+ /// This enables library builds to include proper Ivy type declarations
286+ /// for template type-checking by consumers.
287+ ///
288+ /// The declarations use `i0` as the namespace alias for `@angular/core`.
289+ /// Consumers must ensure their `.d.ts` files include:
290+ /// ```typescript
291+ /// import * as i0 from "@angular/core";
292+ /// ```
293+ pub dts_declarations : Vec < crate :: dts:: DtsDeclaration > ,
279294}
280295
281296impl TransformResult {
@@ -1565,6 +1580,11 @@ pub fn transform_angular_file(
15651580 // Signal-based queries (contentChild(), contentChildren()) are also detected here
15661581 let content_queries = extract_content_queries ( allocator, class) ;
15671582
1583+ // Collect content query property names for .d.ts generation
1584+ // (before content_queries is moved into compile_component_full)
1585+ let content_query_names: Vec < String > =
1586+ content_queries. iter ( ) . map ( |q| q. property_name . to_string ( ) ) . collect ( ) ;
1587+
15681588 // 4. Compile the template and generate ɵcmp/ɵfac
15691589 // Pass the shared pool index to ensure unique constant names
15701590 // Pass the file-level namespace registry to ensure consistent namespace assignments
@@ -1736,6 +1756,20 @@ pub fn transform_angular_file(
17361756 result. dependencies . push ( style_url. to_string ( ) ) ;
17371757 }
17381758
1759+ // Generate .d.ts type declaration for this component
1760+ let type_argument_count = class
1761+ . type_parameters
1762+ . as_ref ( )
1763+ . map_or ( 0 , |tp| tp. params . len ( ) as u32 ) ;
1764+ let has_injectable =
1765+ extract_injectable_metadata ( allocator, class) . is_some ( ) ;
1766+ result. dts_declarations . push ( dts:: generate_component_dts (
1767+ & metadata,
1768+ type_argument_count,
1769+ & content_query_names,
1770+ has_injectable,
1771+ ) ) ;
1772+
17391773 result. component_count += 1 ;
17401774 }
17411775 Err ( diags) => {
@@ -1830,6 +1864,12 @@ pub fn transform_angular_file(
18301864 }
18311865 }
18321866
1867+ // Generate .d.ts type declaration for this directive
1868+ let has_injectable = extract_injectable_metadata ( allocator, class) . is_some ( ) ;
1869+ result
1870+ . dts_declarations
1871+ . push ( dts:: generate_directive_dts ( & directive_metadata, has_injectable) ) ;
1872+
18331873 class_positions. push ( (
18341874 class_name. clone ( ) ,
18351875 compute_effective_start ( class, & decorator_spans_to_remove, stmt_start) ,
@@ -1896,6 +1936,13 @@ pub fn transform_angular_file(
18961936 }
18971937 }
18981938
1939+ // Generate .d.ts type declaration for this pipe
1940+ let has_injectable =
1941+ extract_injectable_metadata ( allocator, class) . is_some ( ) ;
1942+ result
1943+ . dts_declarations
1944+ . push ( dts:: generate_pipe_dts ( & pipe_metadata, has_injectable) ) ;
1945+
18991946 class_positions. push ( (
19001947 class_name. clone ( ) ,
19011948 compute_effective_start ( class, & decorator_spans_to_remove, stmt_start) ,
@@ -1977,6 +2024,13 @@ pub fn transform_angular_file(
19772024 external_decls. push_str ( & emitter. emit_statement ( stmt) ) ;
19782025 }
19792026
2027+ // Generate .d.ts type declaration for this NgModule
2028+ let has_injectable =
2029+ extract_injectable_metadata ( allocator, class) . is_some ( ) ;
2030+ result
2031+ . dts_declarations
2032+ . push ( dts:: generate_ng_module_dts ( & ng_module_metadata, has_injectable) ) ;
2033+
19802034 // NgModule: external_decls go AFTER the class (they reference the class name)
19812035 class_positions. push ( (
19822036 class_name. clone ( ) ,
@@ -2028,6 +2082,11 @@ pub fn transform_angular_file(
20282082 emitter. emit_expression( & definition. prov_definition)
20292083 ) ;
20302084
2085+ // Generate .d.ts type declaration for this injectable
2086+ result
2087+ . dts_declarations
2088+ . push ( dts:: generate_injectable_dts ( & injectable_metadata) ) ;
2089+
20312090 class_positions. push ( (
20322091 class_name. clone ( ) ,
20332092 compute_effective_start ( class, & decorator_spans_to_remove, stmt_start) ,
0 commit comments