Adam Plumer 56731f624a feat(core): add ModuleWithProviders generic type migration (#33217)
Static methods that return a type of ModuleWithProviders currently
do not have to specify a type because the generic falls back to any.
This is problematic because the type of the actual module being
returned is not present in the type information.

Since Ivy uses d.ts files exclusively for downstream packages
(rather than metadata.json files, for example), we no longer have
the type of the actual module being created.

For this reason, a generic type should be added for
ModuleWithProviders that specifies the module type. This will be
required for all users in v10, but will only be necessary for
users of Ivy in v9.

PR Close #33217
2019-10-21 15:53:28 -04:00

32 lines
1.2 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {getImportOfIdentifier} from '../../utils/typescript/imports';
/** Add a generic type to a type reference. */
export function createModuleWithProvidersType(
type: string, node?: ts.TypeReferenceNode): ts.TypeReferenceNode {
const typeNode = node || ts.createTypeReferenceNode('ModuleWithProviders', []);
const typeReferenceNode = ts.createTypeReferenceNode(ts.createIdentifier(type), []);
return ts.updateTypeReferenceNode(
typeNode, typeNode.typeName, ts.createNodeArray([typeReferenceNode]));
}
/** Determine whether a node is a ModuleWithProviders type reference node without a generic type */
export function isModuleWithProvidersNotGeneric(
typeChecker: ts.TypeChecker, node: ts.Node): node is ts.TypeReferenceNode {
if (!ts.isTypeReferenceNode(node) || !ts.isIdentifier(node.typeName)) {
return false;
}
const imp = getImportOfIdentifier(typeChecker, node.typeName);
return !!imp && imp.name === 'ModuleWithProviders' && imp.importModule === '@angular/core' &&
!node.typeArguments;
}