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
This commit is contained in:
parent
b97d770e60
commit
d33e0091df
|
@ -156,7 +156,7 @@ export function extractDirectiveMetadata(
|
||||||
inputs: {...inputsFromMeta, ...inputsFromFields},
|
inputs: {...inputsFromMeta, ...inputsFromFields},
|
||||||
outputs: {...outputsFromMeta, ...outputsFromFields}, queries, selector,
|
outputs: {...outputsFromMeta, ...outputsFromFields}, queries, selector,
|
||||||
type: new WrappedNodeExpr(clazz.name !),
|
type: new WrappedNodeExpr(clazz.name !),
|
||||||
typeArgumentCount: (clazz.typeParameters || []).length,
|
typeArgumentCount: reflector.getGenericArityOfClass(clazz) || 0,
|
||||||
typeSourceSpan: null !, usesInheritance, exportAs,
|
typeSourceSpan: null !, usesInheritance, exportAs,
|
||||||
};
|
};
|
||||||
return {decoratedElements, decorator: directive, metadata};
|
return {decoratedElements, decorator: directive, metadata};
|
||||||
|
|
|
@ -411,4 +411,12 @@ export interface ReflectionHost {
|
||||||
isClass(node: ts.Node): boolean;
|
isClass(node: ts.Node): boolean;
|
||||||
|
|
||||||
hasBaseClass(node: ts.Declaration): 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* Resolve a `ts.Symbol` to its declaration, keeping track of the `viaModule` along the way.
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,7 +17,7 @@ import * as ts from 'typescript';
|
||||||
|
|
||||||
import {ClassMemberKind, ReflectionHost} from '../../host';
|
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.
|
* Represents a value which cannot be determined statically.
|
||||||
|
@ -147,7 +147,7 @@ export class ResolvedReference<T extends ts.Node = ts.Node> extends Reference<T>
|
||||||
// TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support.
|
// TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support.
|
||||||
let relative =
|
let relative =
|
||||||
path.posix.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName)
|
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 './'.
|
// path.relative() does not include the leading './'.
|
||||||
if (!relative.startsWith('.')) {
|
if (!relative.startsWith('.')) {
|
||||||
|
|
Loading…
Reference in New Issue