@@ -62,6 +62,16 @@ export const DI_PARAM_SYMBOLS = new Set([
6262 'forwardRef' ,
6363] ) ;
6464
65+ /** Kinds of nodes which aren't injectable when set as a type of a parameter. */
66+ const UNINJECTABLE_TYPE_KINDS = new Set ( [
67+ ts . SyntaxKind . TrueKeyword ,
68+ ts . SyntaxKind . FalseKeyword ,
69+ ts . SyntaxKind . NumberKeyword ,
70+ ts . SyntaxKind . StringKeyword ,
71+ ts . SyntaxKind . NullKeyword ,
72+ ts . SyntaxKind . VoidKeyword ,
73+ ] ) ;
74+
6575/**
6676 * Finds the necessary information for the `inject` migration in a file.
6777 * @param sourceFile File which to analyze.
@@ -156,9 +166,26 @@ export function analyzeFile(
156166 member . parameters . length > 0 ,
157167 ) as ts . ConstructorDeclaration | undefined ;
158168
169+ // Basic check to determine if all parameters are injectable. This isn't exhaustive, but it
170+ // should catch the majority of cases. An exhaustive check would require a full type checker
171+ // which we don't have in this migration.
172+ const allParamsInjectable = ! ! constructorNode ?. parameters . every ( ( param ) => {
173+ if ( ! param . type || ! UNINJECTABLE_TYPE_KINDS . has ( param . type . kind ) ) {
174+ return true ;
175+ }
176+ return getAngularDecorators ( localTypeChecker , ts . getDecorators ( param ) || [ ] ) . some (
177+ ( dec ) => dec . name === 'Inject' || dec . name === 'Attribute' ,
178+ ) ;
179+ } ) ;
180+
159181 // Don't migrate abstract classes by default, because
160182 // their parameters aren't guaranteed to be injectable.
161- if ( supportsDI && constructorNode && ( ! isAbstract || options . migrateAbstractClasses ) ) {
183+ if (
184+ supportsDI &&
185+ constructorNode &&
186+ allParamsInjectable &&
187+ ( ! isAbstract || options . migrateAbstractClasses )
188+ ) {
162189 classes . push ( {
163190 node,
164191 constructor : constructorNode ,
0 commit comments