@@ -5948,7 +5948,8 @@ namespace ts {
5948
5948
5949
5949
/** A type parameter is thisless if its contraint is thisless, or if it has no constraint. */
5950
5950
function isThislessTypeParameter(node: TypeParameterDeclaration) {
5951
- return !node.constraint || isThislessType(node.constraint);
5951
+ const constraint = getEffectiveConstraintOfTypeParameter(node);
5952
+ return !constraint || isThislessType(constraint);
5952
5953
}
5953
5954
5954
5955
/**
@@ -6735,7 +6736,7 @@ namespace ts {
6735
6736
}
6736
6737
6737
6738
function getConstraintDeclarationForMappedType(type: MappedType) {
6738
- return type.declaration.typeParameter.constraint ;
6739
+ return getEffectiveConstraintOfTypeParameter( type.declaration.typeParameter) ;
6739
6740
}
6740
6741
6741
6742
function isMappedTypeWithKeyofConstraintDeclaration(type: MappedType) {
@@ -7872,7 +7873,7 @@ namespace ts {
7872
7873
7873
7874
function getConstraintDeclaration(type: TypeParameter) {
7874
7875
const decl = type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter);
7875
- return decl && decl.constraint ;
7876
+ return decl && getEffectiveConstraintOfTypeParameter( decl) ;
7876
7877
}
7877
7878
7878
7879
function getInferredTypeParameterConstraint(typeParameter: TypeParameter) {
@@ -7936,7 +7937,9 @@ namespace ts {
7936
7937
}
7937
7938
7938
7939
function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol | undefined {
7939
- return getSymbolOfNode(getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter)!.parent);
7940
+ const tp = getDeclarationOfKind<TypeParameterDeclaration>(typeParameter.symbol, SyntaxKind.TypeParameter)!;
7941
+ const host = isJSDocTemplateTag(tp.parent) ? getHostSignatureFromJSDoc(tp.parent) : tp.parent;
7942
+ return host && getSymbolOfNode(host);
7940
7943
}
7941
7944
7942
7945
function getTypeListId(types: ReadonlyArray<Type> | undefined) {
@@ -22016,7 +22019,7 @@ namespace ts {
22016
22019
checkSourceElement(node.default);
22017
22020
const typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
22018
22021
if (!hasNonCircularBaseConstraint(typeParameter)) {
22019
- error(node.constraint , Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
22022
+ error(getEffectiveConstraintOfTypeParameter( node) , Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
22020
22023
}
22021
22024
if (!hasNonCircularTypeParameterDefault(typeParameter)) {
22022
22025
error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
@@ -22749,7 +22752,7 @@ namespace ts {
22749
22752
22750
22753
const type = <MappedType>getTypeFromMappedTypeNode(node);
22751
22754
const constraintType = getConstraintTypeFromMappedType(type);
22752
- checkTypeAssignableTo(constraintType, keyofConstraintType, node.typeParameter.constraint );
22755
+ checkTypeAssignableTo(constraintType, keyofConstraintType, getEffectiveConstraintOfTypeParameter( node.typeParameter) );
22753
22756
}
22754
22757
22755
22758
function checkThisType(node: ThisTypeNode) {
@@ -23640,6 +23643,13 @@ namespace ts {
23640
23643
checkSourceElement(node.typeExpression);
23641
23644
}
23642
23645
23646
+ function checkJSDocTemplateTag(node: JSDocTemplateTag): void {
23647
+ checkSourceElement(node.constraint);
23648
+ for (const tp of node.typeParameters) {
23649
+ checkSourceElement(tp);
23650
+ }
23651
+ }
23652
+
23643
23653
function checkJSDocTypeTag(node: JSDocTypeTag) {
23644
23654
checkSourceElement(node.typeExpression);
23645
23655
}
@@ -25427,7 +25437,8 @@ namespace ts {
25427
25437
25428
25438
// If the type parameter node does not have an identical constraint as the resolved
25429
25439
// type parameter at this position, we report an error.
25430
- const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
25440
+ const constraint = getEffectiveConstraintOfTypeParameter(source);
25441
+ const sourceConstraint = constraint && getTypeFromTypeNode(constraint);
25431
25442
const targetConstraint = getConstraintOfTypeParameter(target);
25432
25443
if (sourceConstraint) {
25433
25444
// relax check if later interface augmentation has no constraint
@@ -26647,6 +26658,8 @@ namespace ts {
26647
26658
case SyntaxKind.JSDocTypedefTag:
26648
26659
case SyntaxKind.JSDocCallbackTag:
26649
26660
return checkJSDocTypeAliasTag(node as JSDocTypedefTag);
26661
+ case SyntaxKind.JSDocTemplateTag:
26662
+ return checkJSDocTemplateTag(node as JSDocTemplateTag);
26650
26663
case SyntaxKind.JSDocTypeTag:
26651
26664
return checkJSDocTypeTag(node as JSDocTypeTag);
26652
26665
case SyntaxKind.JSDocParameterTag:
@@ -29763,6 +29776,13 @@ namespace ts {
29763
29776
}
29764
29777
return false;
29765
29778
}
29779
+
29780
+ function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined {
29781
+ return node.constraint ? node.constraint
29782
+ : isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0]
29783
+ ? node.parent.constraint
29784
+ : undefined;
29785
+ }
29766
29786
}
29767
29787
29768
29788
/** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
0 commit comments