diff --git a/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts index b99eff1bb8..9b387129b0 100644 --- a/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts @@ -775,6 +775,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0]; if (!node) { + // If the symbol has been imported from a TypeScript typings file then the compiler + // may pass the `prototype` symbol as an export of the class. + // But this has no declaration. In this case we just quietly ignore it. return null; } diff --git a/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts b/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts index 77490430aa..c6ab1d85be 100644 --- a/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts +++ b/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts @@ -228,7 +228,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { protected reflectMembers(symbol: ts.Symbol, decorators?: Decorator[], isStatic?: boolean): ClassMember[]|null { const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0]; - const propertyDefinition = getPropertyDefinition(node); + const propertyDefinition = node && getPropertyDefinition(node); if (propertyDefinition) { const members: ClassMember[] = []; if (propertyDefinition.setter) { diff --git a/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts index b83110b36a..0f93aa57e8 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts @@ -520,6 +520,15 @@ const DECORATED_FILES = [ } ]; +const UNWANTED_PROTOTYPE_EXPORT_FILE = { + name: '/library.d.ts', + contents: ` + export declare class SomeParam { + someInstanceMethod(): void; + static someStaticProp: any; + }` +}; + describe('Esm5ReflectionHost', () => { describe('getDecoratorsOfDeclaration()', () => { @@ -906,6 +915,16 @@ describe('Esm5ReflectionHost', () => { expect(decorators[0].args).toEqual([]); }); }); + + it('should ignore the prototype pseudo-static property on class imported from typings files', + () => { + const program = makeTestProgram(UNWANTED_PROTOTYPE_EXPORT_FILE); + const host = new Esm5ReflectionHost(false, program.getTypeChecker()); + const classNode = getDeclaration( + program, UNWANTED_PROTOTYPE_EXPORT_FILE.name, 'SomeParam', ts.isClassDeclaration); + const members = host.getMembersOfClass(classNode); + expect(members.find(m => m.name === 'prototype')).toBeUndefined(); + }); }); describe('getConstructorParameters', () => {