fix(migrations): preserve type literals and tuples in inject migrations (#58959)

Updates the inject migration to preserve type literals and tuple types, based on some internal feedback.

PR Close #58959
This commit is contained in:
Kristiyan Kostadinov 2024-11-28 19:27:54 +01:00 committed by Pawel Kozlowski
parent 7c5f990001
commit 9cbebc6dda
2 changed files with 61 additions and 6 deletions

View file

@ -553,14 +553,10 @@ function migrateInjectDecorator(
}
}
} else if (
// Pass the type for cases like `@Inject(FOO_TOKEN) foo: Foo`, because:
// 1. It guarantees that the type stays the same as before.
// 2. Avoids leaving unused imports behind.
// We only do this for type references since the `@Inject` pattern above is fairly common and
// apps don't necessarily type their injection tokens correctly, whereas doing it for literal
// types will add a lot of noise to the generated code.
type &&
(ts.isTypeReferenceNode(type) ||
ts.isTypeLiteralNode(type) ||
ts.isTupleTypeNode(type) ||
(ts.isUnionTypeNode(type) && type.types.some(ts.isTypeReferenceNode)))
) {
typeArguments = [type];

View file

@ -1282,6 +1282,65 @@ describe('inject migration', () => {
]);
});
it('should preserve type literals in @Inject parameter', async () => {
writeFile(
'/dir.ts',
[
`import { Directive, Inject } from '@angular/core';`,
`import { FOO_TOKEN } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` constructor(@Inject(FOO_TOKEN) private foo: {id: number}) {}`,
`}`,
].join('\n'),
);
await runMigration();
expect(tree.readContent('/dir.ts').split('\n')).toEqual([
`import { Directive, inject } from '@angular/core';`,
`import { FOO_TOKEN } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` private foo = inject<{`,
` id: number;`,
`}>(FOO_TOKEN);`,
`}`,
]);
});
it('should preserve tuple types in @Inject parameter', async () => {
writeFile(
'/dir.ts',
[
`import { Directive, Inject } from '@angular/core';`,
`import { FOO_TOKEN } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` constructor(@Inject(FOO_TOKEN) private foo: [a: number, b: number]) {}`,
`}`,
].join('\n'),
);
await runMigration();
expect(tree.readContent('/dir.ts').split('\n')).toEqual([
`import { Directive, inject } from '@angular/core';`,
`import { FOO_TOKEN } from 'foo';`,
``,
`@Directive()`,
`class MyDir {`,
` private foo = inject<[`,
` a: number,`,
` b: number`,
`]>(FOO_TOKEN);`,
`}`,
]);
});
it('should unwrap forwardRef with an implicit return', async () => {
writeFile(
'/dir.ts',