fix(compiler): support interface types in injectable constuctors (#14894)
Fixes #12631
This commit is contained in:
@ -9,8 +9,8 @@ import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {MetadataCollector} from './collector';
|
||||
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, MemberMetadata, MetadataArray, MetadataEntry, MetadataError, MetadataImportedSymbolReferenceExpression, MetadataMap, MetadataObject, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isInterfaceMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataImportedSymbolReferenceExpression, isMetadataModuleReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMethodMetadata} from './schema';
|
||||
|
||||
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, MemberMetadata, MetadataArray, MetadataEntry, MetadataError, MetadataImportedSymbolReferenceExpression, MetadataMap, MetadataObject, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataImportedSymbolReferenceExpression, isMetadataModuleReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMethodMetadata} from './schema';
|
||||
|
||||
// The character set used to produce private names.
|
||||
const PRIVATE_NAME_CHARS = [
|
||||
@ -268,6 +268,9 @@ export class MetadataBundler {
|
||||
if (isFunctionMetadata(value)) {
|
||||
return this.convertFunction(moduleName, value);
|
||||
}
|
||||
if (isInterfaceMetadata(value)) {
|
||||
return value;
|
||||
}
|
||||
return this.convertValue(moduleName, value);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {Evaluator, errorSymbol} from './evaluator';
|
||||
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
|
||||
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, InterfaceMetadata, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, VERSION, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
|
||||
import {Symbols} from './symbols';
|
||||
|
||||
// In TypeScript 2.1 these flags moved
|
||||
@ -56,7 +56,8 @@ export class MetadataCollector {
|
||||
*/
|
||||
public getMetadata(sourceFile: ts.SourceFile, strict: boolean = false): ModuleMetadata {
|
||||
const locals = new Symbols(sourceFile);
|
||||
const nodeMap = new Map<MetadataValue|ClassMetadata|FunctionMetadata, ts.Node>();
|
||||
const nodeMap =
|
||||
new Map<MetadataValue|ClassMetadata|InterfaceMetadata|FunctionMetadata, ts.Node>();
|
||||
const evaluator = new Evaluator(locals, nodeMap, this.options);
|
||||
let metadata: {[name: string]: MetadataValue | ClassMetadata | FunctionMetadata}|undefined;
|
||||
let exports: ModuleExportMetadata[];
|
||||
@ -264,13 +265,14 @@ export class MetadataCollector {
|
||||
});
|
||||
|
||||
const isExportedIdentifier = (identifier: ts.Identifier) => exportMap.has(identifier.text);
|
||||
const isExported = (node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration) =>
|
||||
isExport(node) || isExportedIdentifier(node.name);
|
||||
const isExported =
|
||||
(node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration |
|
||||
ts.EnumDeclaration) => isExport(node) || isExportedIdentifier(node.name);
|
||||
const exportedIdentifierName = (identifier: ts.Identifier) =>
|
||||
exportMap.get(identifier.text) || identifier.text;
|
||||
const exportedName =
|
||||
(node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration) =>
|
||||
exportedIdentifierName(node.name);
|
||||
(node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration |
|
||||
ts.EnumDeclaration) => exportedIdentifierName(node.name);
|
||||
|
||||
|
||||
// Predeclare classes and functions
|
||||
@ -290,6 +292,15 @@ export class MetadataCollector {
|
||||
}
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
const interfaceDeclaration = <ts.InterfaceDeclaration>node;
|
||||
if (interfaceDeclaration.name) {
|
||||
const interfaceName = interfaceDeclaration.name.text;
|
||||
// All references to interfaces should be converted to references to `any`.
|
||||
locals.define(interfaceName, {__symbolic: 'reference', name: 'any'});
|
||||
}
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
const functionDeclaration = <ts.FunctionDeclaration>node;
|
||||
if (!isExported(functionDeclaration)) {
|
||||
@ -356,6 +367,14 @@ export class MetadataCollector {
|
||||
// Otherwise don't record metadata for the class.
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
const interfaceDeclaration = <ts.InterfaceDeclaration>node;
|
||||
if (interfaceDeclaration.name && isExported(interfaceDeclaration)) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[exportedName(interfaceDeclaration)] = {__symbolic: 'interface'};
|
||||
}
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
// Record functions that return a single value. Record the parameter
|
||||
// names substitution will be performed by the StaticReflector.
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
export const VERSION = 3;
|
||||
|
||||
export type MetadataEntry = ClassMetadata | FunctionMetadata | MetadataValue;
|
||||
export type MetadataEntry = ClassMetadata | InterfaceMetadata | FunctionMetadata | MetadataValue;
|
||||
|
||||
export interface ModuleMetadata {
|
||||
__symbolic: 'module';
|
||||
@ -47,6 +47,11 @@ export function isClassMetadata(value: any): value is ClassMetadata {
|
||||
return value && value.__symbolic === 'class';
|
||||
}
|
||||
|
||||
export interface InterfaceMetadata { __symbolic: 'interface'; }
|
||||
export function isInterfaceMetadata(value: any): value is InterfaceMetadata {
|
||||
return value && value.__symbolic === 'interface';
|
||||
}
|
||||
|
||||
export interface MetadataMap { [name: string]: MemberMetadata[]; }
|
||||
|
||||
export interface MemberMetadata {
|
||||
|
Reference in New Issue
Block a user