Skip to content

fix(core): distinguish injection tokens based on their value type#47461

Closed
crisbeto wants to merge 1 commit into
angular:mainfrom
crisbeto:46815/injection-token-types
Closed

fix(core): distinguish injection tokens based on their value type#47461
crisbeto wants to merge 1 commit into
angular:mainfrom
crisbeto:46815/injection-token-types

Conversation

@crisbeto

Copy link
Copy Markdown
Member

Currently the generic type of InjectionToken isn't used anywhere which means that the compiler won't flag the following as an error:

const foo = new InjectionToken<number>('foo');
const bar: InjectionToken<string> = foo; // Should be an error, but it's not.

These changes add a private property to allow the compiler to distinguish between the two.

Fixes #46815.

@crisbeto crisbeto force-pushed the 46815/injection-token-types branch 3 times, most recently from a1b96f5 to 8cd5e04 Compare September 16, 2022 09:34
@pkozlowski-opensource pkozlowski-opensource added the area: core Issues related to the framework runtime label Sep 16, 2022
@ngbot ngbot Bot added this to the Backlog milestone Sep 16, 2022
@pkozlowski-opensource pkozlowski-opensource added action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release labels Sep 16, 2022
@crisbeto

Copy link
Copy Markdown
Member Author

This passed a TGP so I'm assuming that it won't be particularly breaking externally either. I'll bump it up to major just in case.

@crisbeto crisbeto added target: major This PR is targeted for the next major release and removed target: patch This PR is targeted for the next patch release labels Sep 16, 2022
Comment thread packages/core/testing/src/test_bed.ts Outdated
Comment thread packages/core/src/di/injection_token.ts Outdated
@crisbeto crisbeto marked this pull request as ready for review September 16, 2022 11:14
Comment thread packages/core/src/di/injection_token.ts Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested how this works when shipped to NPM?

  1. The private modifier causes the type T to be omitted in the shipped d.t.s IIRC (see)
  2. We use stripInternal- so the whole field would be omitted for our consumers (see)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tried packaging and testing it, but I assumed it would be fine since we have other places with these sorts of branding properties.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to test this after packaging and/or add a check in one of the apps within integration folder (where apps work with built packages).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up making it a public __brand__ property. We appear to be using this pattern in a few other places.

@JoostK JoostK Sep 19, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A private field is not stripped from .d.ts files, Paul's playground link shows the following .d.ts output:

export declare class X<T> {
    private p;
}

so it should be possible to make it private, but not @internal. I like the __brand__ naming though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the field is not stripped- but the type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, how did I miss that 🤦‍♂️

@crisbeto crisbeto force-pushed the 46815/injection-token-types branch 2 times, most recently from e8a832c to 4cfaeb9 Compare September 19, 2022 09:44

@AndrewKushnir AndrewKushnir left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@AndrewKushnir AndrewKushnir left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

@jessicajaniuk jessicajaniuk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@jessicajaniuk jessicajaniuk added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Sep 20, 2022
@Harpush

Harpush commented Mar 28, 2023

Copy link
Copy Markdown

@crisbeto any chance for it to land in v16?

@crisbeto

Copy link
Copy Markdown
Member Author

Likely not. I haven't had the time to migrate the internal codebase to avoid the breakages.

@thePunderWoman thePunderWoman removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Nov 22, 2024

@thePunderWoman thePunderWoman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@crisbeto crisbeto modified the milestones: Backlog, v21 Candidate Jun 4, 2025
@crisbeto crisbeto marked this pull request as draft June 4, 2025 14:40
@crisbeto crisbeto force-pushed the 46815/injection-token-types branch from 4cfaeb9 to 911147a Compare September 17, 2025 15:16
@JeanMeche JeanMeche force-pushed the 46815/injection-token-types branch 3 times, most recently from d513b9f to 875b4ad Compare February 7, 2026 18:38
JeanMeche added a commit to JeanMeche/components that referenced this pull request Feb 7, 2026
JeanMeche added a commit to JeanMeche/components that referenced this pull request Feb 7, 2026
JeanMeche added a commit to JeanMeche/components that referenced this pull request Feb 7, 2026
Currently the generic type of `InjectionToken` isn't used anywhere which means that the compiler won't flag the following as an error:

```
const foo = new InjectionToken<number>('foo');
const bar: InjectionToken<string> = foo; // Should be an error, but it's not.
```

These changes add a private property to allow the compiler to distinguish between the two.

Fixes angular#46815.
@JeanMeche JeanMeche force-pushed the 46815/injection-token-types branch from 875b4ad to 3baae5c Compare February 7, 2026 19:09
JeanMeche added a commit to JeanMeche/components that referenced this pull request Feb 8, 2026
JeanMeche added a commit to JeanMeche/components that referenced this pull request Feb 8, 2026
adolgachev pushed a commit to angular/components that referenced this pull request Apr 4, 2026
* refactor(material/sidenav): set generic for the `MAT_DRAWER_CONTAINER` token

cleanup related to angular/angular/pull/47461

* refactor(material/chips): set generic for the `MAT_CHIP` token

cleanup related to angular/angular/pull/47461

* refactor(material/slider): set generic for the `MAT_SLIDER` token

cleanup related to angular/angular/pull/47461

* fixup! refactor(material/chips): set generic for the `MAT_CHIP` token

* refactor(cdk/drag-drop): set generic for the `CDK_DROP_LIST_GROUP` token

cleanup related to angular/angular/pull/47461
adolgachev pushed a commit to angular/components that referenced this pull request Apr 4, 2026
* refactor(material/sidenav): set generic for the `MAT_DRAWER_CONTAINER` token

cleanup related to angular/angular/pull/47461

* refactor(material/chips): set generic for the `MAT_CHIP` token

cleanup related to angular/angular/pull/47461

* refactor(material/slider): set generic for the `MAT_SLIDER` token

cleanup related to angular/angular/pull/47461

* fixup! refactor(material/chips): set generic for the `MAT_CHIP` token

* refactor(cdk/drag-drop): set generic for the `CDK_DROP_LIST_GROUP` token

cleanup related to angular/angular/pull/47461

(cherry picked from commit 8d5a896)
@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

area: core Issues related to the framework runtime state: blocked target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a ghost property to InjectionToken for generic type parameter type safety

8 participants