From d33e0091df673d75e5525f5777dd9640fbeaffb1 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Thu, 9 Aug 2018 14:23:15 +0100 Subject: [PATCH] fix(ivy): emit generic types when needed in defs in .d.ts file (#25406) Ivy definitions in .d.ts files often reference the type of a class. Sometimes, those classes have generic type parameters. When this is the case, ngtsc needs to emit generic type parameters in the .d.ts files (usually by passing 'any'). PR Close #25406 --- .../compiler-cli/src/ngtsc/annotations/src/directive.ts | 2 +- packages/compiler-cli/src/ngtsc/host/src/reflection.ts | 8 ++++++++ packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts | 7 +++++++ packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts | 4 ++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index ce32ab2feb..e67d5bce2b 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -156,7 +156,7 @@ export function extractDirectiveMetadata( inputs: {...inputsFromMeta, ...inputsFromFields}, outputs: {...outputsFromMeta, ...outputsFromFields}, queries, selector, type: new WrappedNodeExpr(clazz.name !), - typeArgumentCount: (clazz.typeParameters || []).length, + typeArgumentCount: reflector.getGenericArityOfClass(clazz) || 0, typeSourceSpan: null !, usesInheritance, exportAs, }; return {decoratedElements, decorator: directive, metadata}; diff --git a/packages/compiler-cli/src/ngtsc/host/src/reflection.ts b/packages/compiler-cli/src/ngtsc/host/src/reflection.ts index 21f4efede4..bb205a125d 100644 --- a/packages/compiler-cli/src/ngtsc/host/src/reflection.ts +++ b/packages/compiler-cli/src/ngtsc/host/src/reflection.ts @@ -411,4 +411,12 @@ export interface ReflectionHost { isClass(node: ts.Node): boolean; hasBaseClass(node: ts.Declaration): boolean; + + /** + * Get the number of generic type parameters of a given class. + * + * @returns the number of type parameters of the class, if known, or `null` if the declaration + * is not a class or has an unknown number of type parameters. + */ + getGenericArityOfClass(clazz: ts.Declaration): number|null; } diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts b/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts index 608dde3c3a..d03bdbd26e 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts @@ -159,6 +159,13 @@ export class TypeScriptReflectionHost implements ReflectionHost { }; } + getGenericArityOfClass(clazz: ts.Declaration): number|null { + if (!ts.isClassDeclaration(clazz)) { + return null; + } + return clazz.typeParameters !== undefined ? clazz.typeParameters.length : 0; + } + /** * Resolve a `ts.Symbol` to its declaration, keeping track of the `viaModule` along the way. * diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts index c3808a60d9..a0988a5e37 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts @@ -17,7 +17,7 @@ import * as ts from 'typescript'; import {ClassMemberKind, ReflectionHost} from '../../host'; -const TS_DTS_EXTENSION = /(\.d)?\.ts$/; +const TS_DTS_JS_EXTENSION = /(\.d)?\.ts|\.js$/; /** * Represents a value which cannot be determined statically. @@ -147,7 +147,7 @@ export class ResolvedReference extends Reference // TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support. let relative = path.posix.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName) - .replace(TS_DTS_EXTENSION, ''); + .replace(TS_DTS_JS_EXTENSION, ''); // path.relative() does not include the leading './'. if (!relative.startsWith('.')) {