Skip to content

fix(compiler-cli): infer correct generic types for directives when so…#57724

Closed
JoostK wants to merge 2 commits into
angular:mainfrom
JoostK:compiler/ttc/partial-type-ctors
Closed

fix(compiler-cli): infer correct generic types for directives when so…#57724
JoostK wants to merge 2 commits into
angular:mainfrom
JoostK:compiler/ttc/partial-type-ctors

Conversation

@JoostK

@JoostK JoostK commented Sep 8, 2024

Copy link
Copy Markdown
Member

…me inputs are omitted

The template type-checker could inadvertently end up inferring any for a directive's generic type argument, effectively disabling all type checking of values of that generic type. This happened when the directive reflects the generic type in multiple inputs, some of which were not bound from the parent template. Since omitted inputs were passed into the directive's type constructor using the 0 as any expression, TypeScript sees the input of type any as inference source of the generic type and locks that in.

The initial remediation idea was to remove omitted inputs from the type-constructor entirely, changing its type from Pick<Dir, 'a'|'...'> to Partial<Pick<Dir, 'a'|'...'>> to make all input bindings optional. This introduces issues where the undefined type that is introduced affects type inference, causing test failures.

Instead, omitted inputs are now passed into the type constructor as never type, which is TypeScript's bottom type such that no inference candidates are introduced.

Fixes #57644


This change is likely (too) breaking, as the inference of the any type used to effectively disable type-checking of any (pun not intended) expressions that reflect a generic type of a directive with missing inputs. MatCalendar is one such directive (the one reported in #57644) that has many inputs that reflect the generic type, where it is typical that not all those inputs are actually bound.

A g3 global presubmit should help determine the impact of the breakage, which may require us to introduce this behind a compiler option.

@JoostK JoostK added breaking changes compiler: template type-checking action: global presubmit The PR is in need of a google3 global presubmit area: compiler Issues related to `ngc`, Angular's template compiler labels Sep 8, 2024
@ngbot ngbot Bot added this to the Backlog milestone Sep 8, 2024
@JoostK
JoostK force-pushed the compiler/ttc/partial-type-ctors branch from a45bf44 to 4b35c7e Compare September 20, 2024 19:28
@angular-robot angular-robot Bot removed the area: compiler Issues related to `ngc`, Angular's template compiler label Sep 20, 2024
@ngbot ngbot Bot removed this from the Backlog milestone Sep 20, 2024
@JoostK
JoostK force-pushed the compiler/ttc/partial-type-ctors branch from 4b35c7e to 7c4614d Compare September 22, 2024 17:03
…me inputs are omitted

The template type-checker could inadvertently end up inferring `any` for a directive's generic type
argument, effectively disabling all type checking of values of that generic type. This happened
when the directive reflects the generic type in multiple inputs, some of which were not bound from
the parent template. Since omitted inputs were passed into the directive's type constructor using
the `0 as any` expression, TypeScript sees the input of type `any` as inference source of the
generic type and locks that in.

The initial remediation idea was to remove omitted inputs from the type-constructor entirely,
changing its type from `Pick<Dir, 'a'|'...'>` to `Partial<Pick<Dir, 'a'|'...'>>` to make all input
bindings optional. This introduces issues where the `undefined` type that is introduced affects
type inference, causing test failures.

Instead, omitted inputs are now passed into the type constructor as `never` type, which is TypeScript's
bottom type such that no inference candidates are introduced.

Fixes angular#57644
@JoostK
JoostK force-pushed the compiler/ttc/partial-type-ctors branch from 7c4614d to 9f60e5b Compare September 29, 2024 20:40
@thePunderWoman

Copy link
Copy Markdown
Contributor

@JoostK Are you still working on this, or can we close it?

@JoostK

JoostK commented Jun 30, 2025

Copy link
Copy Markdown
Member Author

I think this approach is sound and improves type checking accuracy, potentially reporting diagnostics for code that was undesirably deemed valid before. I believe I have revised the implementation since the last TGP so let me rebase the current state and determine the impact using a new TGP. I suspect this may need to be done behind a flag to be able to land this.

@angular-robot

angular-robot Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

This draft PR is being closed because it has been stale for 28 days and has seen no activity from you. If you'd like to see this change land, you can re-open this PR. Thank you for being an Angular contributor!

@angular-robot angular-robot Bot closed this Apr 17, 2026
@angular-automatic-lock-bot

Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators May 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generic types of components/directives are inferred as any when some corresponding inputs are omitted

2 participants