Adding support for @implements. (#36292)
* Adding support for @implements. * Fixed code review issues for @implements, added some more tests. * Fixed declaration emit for @interface * Improved getImplementsTypes to not cache the results since it is only used once. * Removed unnecessary checks from getImplementsTypes
This commit is contained in:
parent
e3ec3d1942
commit
f883bf3acb
|
@ -5889,9 +5889,13 @@ namespace ts {
|
|||
const typeParamDecls = map(localParams, p => typeParameterToDeclaration(p, context));
|
||||
const classType = getDeclaredTypeOfClassOrInterface(symbol);
|
||||
const baseTypes = getBaseTypes(classType);
|
||||
const implementsTypes = getImplementsTypes(classType);
|
||||
const staticType = getTypeOfSymbol(symbol);
|
||||
const staticBaseType = getBaseConstructorTypeOfClass(staticType as InterfaceType);
|
||||
const heritageClauses = !length(baseTypes) ? undefined : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))];
|
||||
const heritageClauses = [
|
||||
...!length(baseTypes) ? [] : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))],
|
||||
...!length(implementsTypes) ? [] : [createHeritageClause(SyntaxKind.ImplementsKeyword, map(implementsTypes, b => serializeBaseType(b, staticBaseType, localName)))]
|
||||
];
|
||||
const symbolProps = getPropertiesOfType(classType);
|
||||
const publicSymbolProps = filter(symbolProps, s => {
|
||||
const valueDecl = s.valueDeclaration;
|
||||
|
@ -8251,6 +8255,26 @@ namespace ts {
|
|||
return type.resolvedBaseConstructorType;
|
||||
}
|
||||
|
||||
function getImplementsTypes(type: InterfaceType): BaseType[] {
|
||||
let resolvedImplementsTypes: BaseType[] = emptyArray;
|
||||
for (const declaration of type.symbol.declarations) {
|
||||
const implementsTypeNodes = getEffectiveImplementsTypeNodes(declaration as ClassLikeDeclaration);
|
||||
if (!implementsTypeNodes) continue;
|
||||
for (const node of implementsTypeNodes) {
|
||||
const implementsType = getTypeFromTypeNode(node);
|
||||
if (implementsType !== errorType) {
|
||||
if (resolvedImplementsTypes === emptyArray) {
|
||||
resolvedImplementsTypes = [<ObjectType>implementsType];
|
||||
}
|
||||
else {
|
||||
resolvedImplementsTypes.push(implementsType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return resolvedImplementsTypes;
|
||||
}
|
||||
|
||||
function getBaseTypes(type: InterfaceType): BaseType[] {
|
||||
if (!type.resolvedBaseTypes) {
|
||||
if (type.objectFlags & ObjectFlags.Tuple) {
|
||||
|
@ -30339,6 +30363,13 @@ namespace ts {
|
|||
checkSignatureDeclaration(node);
|
||||
}
|
||||
|
||||
function checkJSDocImplementsTag(node: JSDocImplementsTag): void {
|
||||
const classLike = getJSDocHost(node);
|
||||
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
|
||||
error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void {
|
||||
const classLike = getJSDocHost(node);
|
||||
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
|
||||
|
@ -32609,7 +32640,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const implementedTypeNodes = getClassImplementsHeritageClauseElements(node);
|
||||
const implementedTypeNodes = getEffectiveImplementsTypeNodes(node);
|
||||
if (implementedTypeNodes) {
|
||||
for (const typeRefNode of implementedTypeNodes) {
|
||||
if (!isEntityNameExpression(typeRefNode.expression)) {
|
||||
|
@ -33829,6 +33860,8 @@ namespace ts {
|
|||
return checkImportType(<ImportTypeNode>node);
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
|
||||
case SyntaxKind.JSDocImplementsTag:
|
||||
return checkJSDocImplementsTag(node as JSDocImplementsTag);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
|
|
|
@ -1519,8 +1519,9 @@ namespace ts {
|
|||
case SyntaxKind.JSDocThisTag:
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
return emitJSDocSimpleTypedTag(node as JSDocTypeTag);
|
||||
case SyntaxKind.JSDocImplementsTag:
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return emitJSDocAugmentsTag(node as JSDocAugmentsTag);
|
||||
return emitJSDocHeritageTag(node as JSDocImplementsTag | JSDocAugmentsTag);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return emitJSDocTemplateTag(node as JSDocTemplateTag);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
|
@ -3468,7 +3469,7 @@ namespace ts {
|
|||
emitJSDocComment(tag.comment);
|
||||
}
|
||||
|
||||
function emitJSDocAugmentsTag(tag: JSDocAugmentsTag) {
|
||||
function emitJSDocHeritageTag(tag: JSDocImplementsTag | JSDocAugmentsTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
writeSpace();
|
||||
writePunctuation("{");
|
||||
|
|
|
@ -479,6 +479,9 @@ namespace ts {
|
|||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name));
|
||||
case SyntaxKind.JSDocAuthorTag:
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName);
|
||||
case SyntaxKind.JSDocImplementsTag:
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocImplementsTag>node).class);
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
|
@ -6999,6 +7002,9 @@ namespace ts {
|
|||
case "author":
|
||||
tag = parseAuthorTag(start, tagName, margin);
|
||||
break;
|
||||
case "implements":
|
||||
tag = parseImplementsTag(start, tagName);
|
||||
break;
|
||||
case "augments":
|
||||
case "extends":
|
||||
tag = parseAugmentsTag(start, tagName);
|
||||
|
@ -7355,6 +7361,13 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function parseImplementsTag(start: number, tagName: Identifier): JSDocImplementsTag {
|
||||
const result = <JSDocImplementsTag>createNode(SyntaxKind.JSDocImplementsTag, start);
|
||||
result.tagName = tagName;
|
||||
result.class = parseExpressionWithTypeArgumentsForAugments();
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag {
|
||||
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, start);
|
||||
result.tagName = tagName;
|
||||
|
|
|
@ -471,6 +471,7 @@ namespace ts {
|
|||
JSDocSignature,
|
||||
JSDocTag,
|
||||
JSDocAugmentsTag,
|
||||
JSDocImplementsTag,
|
||||
JSDocAuthorTag,
|
||||
JSDocClassTag,
|
||||
JSDocPublicTag,
|
||||
|
@ -1986,7 +1987,7 @@ namespace ts {
|
|||
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
|
@ -2660,6 +2661,11 @@ namespace ts {
|
|||
class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression };
|
||||
}
|
||||
|
||||
export interface JSDocImplementsTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocImplementsTag;
|
||||
class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression };
|
||||
}
|
||||
|
||||
export interface JSDocAuthorTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocAuthorTag;
|
||||
}
|
||||
|
|
|
@ -2807,15 +2807,20 @@ namespace ts {
|
|||
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
|
||||
}
|
||||
|
||||
export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) {
|
||||
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
|
||||
return heritageClause ? heritageClause.types : undefined;
|
||||
export function getEffectiveImplementsTypeNodes(node: ClassLikeDeclaration): undefined | readonly ExpressionWithTypeArguments[]{
|
||||
if(isInJSFile(node)) {
|
||||
return getJSDocImplementsTags(node).map(n => n.class);
|
||||
}
|
||||
else {
|
||||
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
|
||||
return heritageClause?.types;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the node in an `extends` or `implements` clause of a class or interface. */
|
||||
export function getAllSuperTypeNodes(node: Node): readonly TypeNode[] {
|
||||
return isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || emptyArray :
|
||||
isClassLike(node) ? concatenate(singleElementArray(getEffectiveBaseTypeNode(node)), getClassImplementsHeritageClauseElements(node)) || emptyArray :
|
||||
isClassLike(node) ? concatenate(singleElementArray(getEffectiveBaseTypeNode(node)), getEffectiveImplementsTypeNodes(node)) || emptyArray :
|
||||
emptyArray;
|
||||
}
|
||||
|
||||
|
|
|
@ -671,6 +671,11 @@ namespace ts {
|
|||
return getFirstJSDocTag(node, isJSDocAugmentsTag);
|
||||
}
|
||||
|
||||
/** Gets the JSDoc implements tags for the node if present */
|
||||
export function getJSDocImplementsTags(node: Node): readonly JSDocImplementsTag[] {
|
||||
return getAllJSDocTags(node, isJSDocImplementsTag);
|
||||
}
|
||||
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
export function getJSDocClassTag(node: Node): JSDocClassTag | undefined {
|
||||
return getFirstJSDocTag(node, isJSDocClassTag);
|
||||
|
@ -787,7 +792,12 @@ namespace ts {
|
|||
return find(getJSDocTags(node), predicate);
|
||||
}
|
||||
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
/** Gets all JSDoc tags that match a specified predicate */
|
||||
export function getAllJSDocTags<T extends JSDocTag>(node: Node, predicate: (tag: JSDocTag) => tag is T): readonly T[] {
|
||||
return getJSDocTags(node).filter(predicate);
|
||||
}
|
||||
|
||||
/** Gets all JSDoc tags of a specified kind */
|
||||
export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JSDocTag[] {
|
||||
return getJSDocTags(node).filter(doc => doc.kind === kind);
|
||||
}
|
||||
|
@ -1582,6 +1592,10 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.JSDocAugmentsTag;
|
||||
}
|
||||
|
||||
export function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag {
|
||||
return node.kind === SyntaxKind.JSDocImplementsTag;
|
||||
}
|
||||
|
||||
export function isJSDocClassTag(node: Node): node is JSDocClassTag {
|
||||
return node.kind === SyntaxKind.JSDocClassTag;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ts.codefix {
|
|||
getCodeActions(context) {
|
||||
const { sourceFile, span } = context;
|
||||
const classDeclaration = getClass(sourceFile, span.start);
|
||||
return mapDefined<ExpressionWithTypeArguments, CodeFixAction>(getClassImplementsHeritageClauseElements(classDeclaration), implementedTypeNode => {
|
||||
return mapDefined<ExpressionWithTypeArguments, CodeFixAction>(getEffectiveImplementsTypeNodes(classDeclaration), implementedTypeNode => {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingDeclarations(context, implementedTypeNode, sourceFile, classDeclaration, t, context.preferences));
|
||||
return changes.length === 0 ? undefined : createCodeFixAction(fixId, changes, [Diagnostics.Implement_interface_0, implementedTypeNode.getText(sourceFile)], fixId, Diagnostics.Implement_all_unimplemented_interfaces);
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ namespace ts.codefix {
|
|||
return codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const classDeclaration = getClass(diag.file, diag.start);
|
||||
if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) {
|
||||
for (const implementedTypeNode of getClassImplementsHeritageClauseElements(classDeclaration)!) {
|
||||
for (const implementedTypeNode of getEffectiveImplementsTypeNodes(classDeclaration)!) {
|
||||
addMissingDeclarations(context, implementedTypeNode, diag.file, classDeclaration, changes, context.preferences);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,8 @@ namespace ts.JsDoc {
|
|||
function getCommentText(tag: JSDocTag): string | undefined {
|
||||
const { comment } = tag;
|
||||
switch (tag.kind) {
|
||||
case SyntaxKind.JSDocImplementsTag:
|
||||
return withNode((tag as JSDocImplementsTag).class);
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return withNode((tag as JSDocAugmentsTag).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
|
|
|
@ -383,29 +383,30 @@ declare namespace ts {
|
|||
JSDocSignature = 305,
|
||||
JSDocTag = 306,
|
||||
JSDocAugmentsTag = 307,
|
||||
JSDocAuthorTag = 308,
|
||||
JSDocClassTag = 309,
|
||||
JSDocPublicTag = 310,
|
||||
JSDocPrivateTag = 311,
|
||||
JSDocProtectedTag = 312,
|
||||
JSDocReadonlyTag = 313,
|
||||
JSDocCallbackTag = 314,
|
||||
JSDocEnumTag = 315,
|
||||
JSDocParameterTag = 316,
|
||||
JSDocReturnTag = 317,
|
||||
JSDocThisTag = 318,
|
||||
JSDocTypeTag = 319,
|
||||
JSDocTemplateTag = 320,
|
||||
JSDocTypedefTag = 321,
|
||||
JSDocPropertyTag = 322,
|
||||
SyntaxList = 323,
|
||||
NotEmittedStatement = 324,
|
||||
PartiallyEmittedExpression = 325,
|
||||
CommaListExpression = 326,
|
||||
MergeDeclarationMarker = 327,
|
||||
EndOfDeclarationMarker = 328,
|
||||
SyntheticReferenceExpression = 329,
|
||||
Count = 330,
|
||||
JSDocImplementsTag = 308,
|
||||
JSDocAuthorTag = 309,
|
||||
JSDocClassTag = 310,
|
||||
JSDocPublicTag = 311,
|
||||
JSDocPrivateTag = 312,
|
||||
JSDocProtectedTag = 313,
|
||||
JSDocReadonlyTag = 314,
|
||||
JSDocCallbackTag = 315,
|
||||
JSDocEnumTag = 316,
|
||||
JSDocParameterTag = 317,
|
||||
JSDocReturnTag = 318,
|
||||
JSDocThisTag = 319,
|
||||
JSDocTypeTag = 320,
|
||||
JSDocTemplateTag = 321,
|
||||
JSDocTypedefTag = 322,
|
||||
JSDocPropertyTag = 323,
|
||||
SyntaxList = 324,
|
||||
NotEmittedStatement = 325,
|
||||
PartiallyEmittedExpression = 326,
|
||||
CommaListExpression = 327,
|
||||
MergeDeclarationMarker = 328,
|
||||
EndOfDeclarationMarker = 329,
|
||||
SyntheticReferenceExpression = 330,
|
||||
Count = 331,
|
||||
FirstAssignment = 62,
|
||||
LastAssignment = 74,
|
||||
FirstCompoundAssignment = 63,
|
||||
|
@ -434,9 +435,9 @@ declare namespace ts {
|
|||
LastStatement = 241,
|
||||
FirstNode = 153,
|
||||
FirstJSDocNode = 294,
|
||||
LastJSDocNode = 322,
|
||||
LastJSDocNode = 323,
|
||||
FirstJSDocTagNode = 306,
|
||||
LastJSDocTagNode = 322,
|
||||
LastJSDocTagNode = 323,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
|
@ -1145,7 +1146,7 @@ declare namespace ts {
|
|||
}
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
export interface NewExpression extends PrimaryExpression, Declaration {
|
||||
|
@ -1635,6 +1636,12 @@ declare namespace ts {
|
|||
expression: Identifier | PropertyAccessEntityNameExpression;
|
||||
};
|
||||
}
|
||||
export interface JSDocImplementsTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocImplementsTag;
|
||||
class: ExpressionWithTypeArguments & {
|
||||
expression: Identifier | PropertyAccessEntityNameExpression;
|
||||
};
|
||||
}
|
||||
export interface JSDocAuthorTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocAuthorTag;
|
||||
}
|
||||
|
@ -3516,6 +3523,8 @@ declare namespace ts {
|
|||
function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean;
|
||||
/** Gets the JSDoc augments tag for the node if present */
|
||||
function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined;
|
||||
/** Gets the JSDoc implements tags for the node if present */
|
||||
function getJSDocImplementsTags(node: Node): readonly JSDocImplementsTag[];
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
function getJSDocClassTag(node: Node): JSDocClassTag | undefined;
|
||||
/** Gets the JSDoc public tag for the node if present */
|
||||
|
@ -3557,7 +3566,9 @@ declare namespace ts {
|
|||
function getJSDocReturnType(node: Node): TypeNode | undefined;
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
function getJSDocTags(node: Node): readonly JSDocTag[];
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
/** Gets all JSDoc tags that match a specified predicate */
|
||||
function getAllJSDocTags<T extends JSDocTag>(node: Node, predicate: (tag: JSDocTag) => tag is T): readonly T[];
|
||||
/** Gets all JSDoc tags of a specified kind */
|
||||
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JSDocTag[];
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
|
@ -3733,6 +3744,7 @@ declare namespace ts {
|
|||
function isJSDoc(node: Node): node is JSDoc;
|
||||
function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag;
|
||||
function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag;
|
||||
function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag;
|
||||
function isJSDocClassTag(node: Node): node is JSDocClassTag;
|
||||
function isJSDocPublicTag(node: Node): node is JSDocPublicTag;
|
||||
function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag;
|
||||
|
|
66
tests/baselines/reference/api/typescript.d.ts
vendored
66
tests/baselines/reference/api/typescript.d.ts
vendored
|
@ -383,29 +383,30 @@ declare namespace ts {
|
|||
JSDocSignature = 305,
|
||||
JSDocTag = 306,
|
||||
JSDocAugmentsTag = 307,
|
||||
JSDocAuthorTag = 308,
|
||||
JSDocClassTag = 309,
|
||||
JSDocPublicTag = 310,
|
||||
JSDocPrivateTag = 311,
|
||||
JSDocProtectedTag = 312,
|
||||
JSDocReadonlyTag = 313,
|
||||
JSDocCallbackTag = 314,
|
||||
JSDocEnumTag = 315,
|
||||
JSDocParameterTag = 316,
|
||||
JSDocReturnTag = 317,
|
||||
JSDocThisTag = 318,
|
||||
JSDocTypeTag = 319,
|
||||
JSDocTemplateTag = 320,
|
||||
JSDocTypedefTag = 321,
|
||||
JSDocPropertyTag = 322,
|
||||
SyntaxList = 323,
|
||||
NotEmittedStatement = 324,
|
||||
PartiallyEmittedExpression = 325,
|
||||
CommaListExpression = 326,
|
||||
MergeDeclarationMarker = 327,
|
||||
EndOfDeclarationMarker = 328,
|
||||
SyntheticReferenceExpression = 329,
|
||||
Count = 330,
|
||||
JSDocImplementsTag = 308,
|
||||
JSDocAuthorTag = 309,
|
||||
JSDocClassTag = 310,
|
||||
JSDocPublicTag = 311,
|
||||
JSDocPrivateTag = 312,
|
||||
JSDocProtectedTag = 313,
|
||||
JSDocReadonlyTag = 314,
|
||||
JSDocCallbackTag = 315,
|
||||
JSDocEnumTag = 316,
|
||||
JSDocParameterTag = 317,
|
||||
JSDocReturnTag = 318,
|
||||
JSDocThisTag = 319,
|
||||
JSDocTypeTag = 320,
|
||||
JSDocTemplateTag = 321,
|
||||
JSDocTypedefTag = 322,
|
||||
JSDocPropertyTag = 323,
|
||||
SyntaxList = 324,
|
||||
NotEmittedStatement = 325,
|
||||
PartiallyEmittedExpression = 326,
|
||||
CommaListExpression = 327,
|
||||
MergeDeclarationMarker = 328,
|
||||
EndOfDeclarationMarker = 329,
|
||||
SyntheticReferenceExpression = 330,
|
||||
Count = 331,
|
||||
FirstAssignment = 62,
|
||||
LastAssignment = 74,
|
||||
FirstCompoundAssignment = 63,
|
||||
|
@ -434,9 +435,9 @@ declare namespace ts {
|
|||
LastStatement = 241,
|
||||
FirstNode = 153,
|
||||
FirstJSDocNode = 294,
|
||||
LastJSDocNode = 322,
|
||||
LastJSDocNode = 323,
|
||||
FirstJSDocTagNode = 306,
|
||||
LastJSDocTagNode = 322,
|
||||
LastJSDocTagNode = 323,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
|
@ -1145,7 +1146,7 @@ declare namespace ts {
|
|||
}
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
export interface NewExpression extends PrimaryExpression, Declaration {
|
||||
|
@ -1635,6 +1636,12 @@ declare namespace ts {
|
|||
expression: Identifier | PropertyAccessEntityNameExpression;
|
||||
};
|
||||
}
|
||||
export interface JSDocImplementsTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocImplementsTag;
|
||||
class: ExpressionWithTypeArguments & {
|
||||
expression: Identifier | PropertyAccessEntityNameExpression;
|
||||
};
|
||||
}
|
||||
export interface JSDocAuthorTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocAuthorTag;
|
||||
}
|
||||
|
@ -3516,6 +3523,8 @@ declare namespace ts {
|
|||
function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean;
|
||||
/** Gets the JSDoc augments tag for the node if present */
|
||||
function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined;
|
||||
/** Gets the JSDoc implements tags for the node if present */
|
||||
function getJSDocImplementsTags(node: Node): readonly JSDocImplementsTag[];
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
function getJSDocClassTag(node: Node): JSDocClassTag | undefined;
|
||||
/** Gets the JSDoc public tag for the node if present */
|
||||
|
@ -3557,7 +3566,9 @@ declare namespace ts {
|
|||
function getJSDocReturnType(node: Node): TypeNode | undefined;
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
function getJSDocTags(node: Node): readonly JSDocTag[];
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
/** Gets all JSDoc tags that match a specified predicate */
|
||||
function getAllJSDocTags<T extends JSDocTag>(node: Node, predicate: (tag: JSDocTag) => tag is T): readonly T[];
|
||||
/** Gets all JSDoc tags of a specified kind */
|
||||
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JSDocTag[];
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
|
@ -3733,6 +3744,7 @@ declare namespace ts {
|
|||
function isJSDoc(node: Node): node is JSDoc;
|
||||
function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag;
|
||||
function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag;
|
||||
function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag;
|
||||
function isJSDocClassTag(node: Node): node is JSDocClassTag;
|
||||
function isJSDocPublicTag(node: Node): node is JSDocPublicTag;
|
||||
function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag;
|
||||
|
|
35
tests/baselines/reference/jsdocImplements_class.errors.txt
Normal file
35
tests/baselines/reference/jsdocImplements_class.errors.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
/a.js(13,5): error TS2416: Property 'method' in type 'B2' is not assignable to the same property in base type 'A'.
|
||||
Type '() => string' is not assignable to type '() => number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
/a.js(17,7): error TS2720: Class 'B3' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
|
||||
Property 'method' is missing in type 'B3' but required in type 'A'.
|
||||
|
||||
|
||||
==== /a.js (2 errors) ====
|
||||
class A {
|
||||
/** @return {number} */
|
||||
method() { throw new Error(); }
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B {
|
||||
method() { return 0 }
|
||||
}
|
||||
|
||||
/** @implements A */
|
||||
class B2 {
|
||||
/** @return {string} */
|
||||
method() { return "" }
|
||||
~~~~~~
|
||||
!!! error TS2416: Property 'method' in type 'B2' is not assignable to the same property in base type 'A'.
|
||||
!!! error TS2416: Type '() => string' is not assignable to type '() => number'.
|
||||
!!! error TS2416: Type 'string' is not assignable to type 'number'.
|
||||
}
|
||||
|
||||
/** @implements {A} */
|
||||
class B3 {
|
||||
~~
|
||||
!!! error TS2720: Class 'B3' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
|
||||
!!! error TS2720: Property 'method' is missing in type 'B3' but required in type 'A'.
|
||||
!!! related TS2728 /a.js:3:5: 'method' is declared here.
|
||||
}
|
||||
|
40
tests/baselines/reference/jsdocImplements_class.js
Normal file
40
tests/baselines/reference/jsdocImplements_class.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
//// [a.js]
|
||||
class A {
|
||||
/** @return {number} */
|
||||
method() { throw new Error(); }
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B {
|
||||
method() { return 0 }
|
||||
}
|
||||
|
||||
/** @implements A */
|
||||
class B2 {
|
||||
/** @return {string} */
|
||||
method() { return "" }
|
||||
}
|
||||
|
||||
/** @implements {A} */
|
||||
class B3 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
declare class A {
|
||||
/** @return {number} */
|
||||
method(): number;
|
||||
}
|
||||
/** @implements {A} */
|
||||
declare class B implements A {
|
||||
method(): number;
|
||||
}
|
||||
/** @implements A */
|
||||
declare class B2 implements A {
|
||||
/** @return {string} */
|
||||
method(): string;
|
||||
}
|
||||
/** @implements {A} */
|
||||
declare class B3 implements A {
|
||||
}
|
31
tests/baselines/reference/jsdocImplements_class.symbols
Normal file
31
tests/baselines/reference/jsdocImplements_class.symbols
Normal file
|
@ -0,0 +1,31 @@
|
|||
=== /a.js ===
|
||||
class A {
|
||||
>A : Symbol(A, Decl(a.js, 0, 0))
|
||||
|
||||
/** @return {number} */
|
||||
method() { throw new Error(); }
|
||||
>method : Symbol(A.method, Decl(a.js, 0, 9))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B {
|
||||
>B : Symbol(B, Decl(a.js, 3, 1))
|
||||
|
||||
method() { return 0 }
|
||||
>method : Symbol(B.method, Decl(a.js, 5, 10))
|
||||
}
|
||||
|
||||
/** @implements A */
|
||||
class B2 {
|
||||
>B2 : Symbol(B2, Decl(a.js, 7, 1))
|
||||
|
||||
/** @return {string} */
|
||||
method() { return "" }
|
||||
>method : Symbol(B2.method, Decl(a.js, 10, 11))
|
||||
}
|
||||
|
||||
/** @implements {A} */
|
||||
class B3 {
|
||||
>B3 : Symbol(B3, Decl(a.js, 13, 1))
|
||||
}
|
||||
|
34
tests/baselines/reference/jsdocImplements_class.types
Normal file
34
tests/baselines/reference/jsdocImplements_class.types
Normal file
|
@ -0,0 +1,34 @@
|
|||
=== /a.js ===
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
/** @return {number} */
|
||||
method() { throw new Error(); }
|
||||
>method : () => number
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B {
|
||||
>B : B
|
||||
|
||||
method() { return 0 }
|
||||
>method : () => number
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
/** @implements A */
|
||||
class B2 {
|
||||
>B2 : B2
|
||||
|
||||
/** @return {string} */
|
||||
method() { return "" }
|
||||
>method : () => string
|
||||
>"" : ""
|
||||
}
|
||||
|
||||
/** @implements {A} */
|
||||
class B3 {
|
||||
>B3 : B3
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/a.js(9,5): error TS2416: Property 'mNumber' in type 'B2' is not assignable to the same property in base type 'A'.
|
||||
Type '() => string' is not assignable to type '() => number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
/a.js(14,7): error TS2420: Class 'B3' incorrectly implements interface 'A'.
|
||||
Property 'mNumber' is missing in type 'B3' but required in type 'A'.
|
||||
|
||||
|
||||
==== /defs.d.ts (0 errors) ====
|
||||
interface A {
|
||||
mNumber(): number;
|
||||
}
|
||||
==== /a.js (2 errors) ====
|
||||
/** @implements A */
|
||||
class B {
|
||||
mNumber() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B2 {
|
||||
mNumber() {
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'mNumber' in type 'B2' is not assignable to the same property in base type 'A'.
|
||||
!!! error TS2416: Type '() => string' is not assignable to type '() => number'.
|
||||
!!! error TS2416: Type 'string' is not assignable to type 'number'.
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/** @implements A */
|
||||
class B3 {
|
||||
~~
|
||||
!!! error TS2420: Class 'B3' incorrectly implements interface 'A'.
|
||||
!!! error TS2420: Property 'mNumber' is missing in type 'B3' but required in type 'A'.
|
||||
!!! related TS2728 /defs.d.ts:2:5: 'mNumber' is declared here.
|
||||
}
|
||||
|
38
tests/baselines/reference/jsdocImplements_interface.js
Normal file
38
tests/baselines/reference/jsdocImplements_interface.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
//// [tests/cases/conformance/jsdoc/jsdocImplements_interface.ts] ////
|
||||
|
||||
//// [defs.d.ts]
|
||||
interface A {
|
||||
mNumber(): number;
|
||||
}
|
||||
//// [a.js]
|
||||
/** @implements A */
|
||||
class B {
|
||||
mNumber() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B2 {
|
||||
mNumber() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/** @implements A */
|
||||
class B3 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
/** @implements A */
|
||||
declare class B implements A {
|
||||
mNumber(): number;
|
||||
}
|
||||
/** @implements {A} */
|
||||
declare class B2 implements A {
|
||||
mNumber(): string;
|
||||
}
|
||||
/** @implements A */
|
||||
declare class B3 implements A {
|
||||
}
|
33
tests/baselines/reference/jsdocImplements_interface.symbols
Normal file
33
tests/baselines/reference/jsdocImplements_interface.symbols
Normal file
|
@ -0,0 +1,33 @@
|
|||
=== /defs.d.ts ===
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(defs.d.ts, 0, 0))
|
||||
|
||||
mNumber(): number;
|
||||
>mNumber : Symbol(A.mNumber, Decl(defs.d.ts, 0, 13))
|
||||
}
|
||||
=== /a.js ===
|
||||
/** @implements A */
|
||||
class B {
|
||||
>B : Symbol(B, Decl(a.js, 0, 0))
|
||||
|
||||
mNumber() {
|
||||
>mNumber : Symbol(B.mNumber, Decl(a.js, 1, 9))
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B2 {
|
||||
>B2 : Symbol(B2, Decl(a.js, 5, 1))
|
||||
|
||||
mNumber() {
|
||||
>mNumber : Symbol(B2.mNumber, Decl(a.js, 7, 10))
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/** @implements A */
|
||||
class B3 {
|
||||
>B3 : Symbol(B3, Decl(a.js, 11, 1))
|
||||
}
|
||||
|
33
tests/baselines/reference/jsdocImplements_interface.types
Normal file
33
tests/baselines/reference/jsdocImplements_interface.types
Normal file
|
@ -0,0 +1,33 @@
|
|||
=== /defs.d.ts ===
|
||||
interface A {
|
||||
mNumber(): number;
|
||||
>mNumber : () => number
|
||||
}
|
||||
=== /a.js ===
|
||||
/** @implements A */
|
||||
class B {
|
||||
>B : B
|
||||
|
||||
mNumber() {
|
||||
>mNumber : () => number
|
||||
|
||||
return 0;
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B2 {
|
||||
>B2 : B2
|
||||
|
||||
mNumber() {
|
||||
>mNumber : () => string
|
||||
|
||||
return "";
|
||||
>"" : ""
|
||||
}
|
||||
}
|
||||
/** @implements A */
|
||||
class B3 {
|
||||
>B3 : B3
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/a.js(17,7): error TS2420: Class 'BadSquare' incorrectly implements interface 'Drawable'.
|
||||
Property 'draw' is missing in type 'BadSquare' but required in type 'Drawable'.
|
||||
|
||||
|
||||
==== /defs.d.ts (0 errors) ====
|
||||
interface Drawable {
|
||||
draw(): number;
|
||||
}
|
||||
interface Sizable {
|
||||
size(): number;
|
||||
}
|
||||
==== /a.js (1 errors) ====
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
class Square {
|
||||
draw() {
|
||||
return 0;
|
||||
}
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
class BadSquare {
|
||||
~~~~~~~~~
|
||||
!!! error TS2420: Class 'BadSquare' incorrectly implements interface 'Drawable'.
|
||||
!!! error TS2420: Property 'draw' is missing in type 'BadSquare' but required in type 'Drawable'.
|
||||
!!! related TS2728 /defs.d.ts:2:5: 'draw' is declared here.
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//// [tests/cases/conformance/jsdoc/jsdocImplements_interface_multiple.ts] ////
|
||||
|
||||
//// [defs.d.ts]
|
||||
interface Drawable {
|
||||
draw(): number;
|
||||
}
|
||||
interface Sizable {
|
||||
size(): number;
|
||||
}
|
||||
//// [a.js]
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
class Square {
|
||||
draw() {
|
||||
return 0;
|
||||
}
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
class BadSquare {
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
declare class Square implements Drawable, Sizable {
|
||||
draw(): number;
|
||||
size(): number;
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
declare class BadSquare implements Drawable, Sizable {
|
||||
size(): number;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
=== /defs.d.ts ===
|
||||
interface Drawable {
|
||||
>Drawable : Symbol(Drawable, Decl(defs.d.ts, 0, 0))
|
||||
|
||||
draw(): number;
|
||||
>draw : Symbol(Drawable.draw, Decl(defs.d.ts, 0, 20))
|
||||
}
|
||||
interface Sizable {
|
||||
>Sizable : Symbol(Sizable, Decl(defs.d.ts, 2, 1))
|
||||
|
||||
size(): number;
|
||||
>size : Symbol(Sizable.size, Decl(defs.d.ts, 3, 19))
|
||||
}
|
||||
=== /a.js ===
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
class Square {
|
||||
>Square : Symbol(Square, Decl(a.js, 0, 0))
|
||||
|
||||
draw() {
|
||||
>draw : Symbol(Square.draw, Decl(a.js, 4, 14))
|
||||
|
||||
return 0;
|
||||
}
|
||||
size() {
|
||||
>size : Symbol(Square.size, Decl(a.js, 7, 5))
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
class BadSquare {
|
||||
>BadSquare : Symbol(BadSquare, Decl(a.js, 11, 1))
|
||||
|
||||
size() {
|
||||
>size : Symbol(BadSquare.size, Decl(a.js, 16, 17))
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
=== /defs.d.ts ===
|
||||
interface Drawable {
|
||||
draw(): number;
|
||||
>draw : () => number
|
||||
}
|
||||
interface Sizable {
|
||||
size(): number;
|
||||
>size : () => number
|
||||
}
|
||||
=== /a.js ===
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
class Square {
|
||||
>Square : Square
|
||||
|
||||
draw() {
|
||||
>draw : () => number
|
||||
|
||||
return 0;
|
||||
>0 : 0
|
||||
}
|
||||
size() {
|
||||
>size : () => number
|
||||
|
||||
return 0;
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
class BadSquare {
|
||||
>BadSquare : BadSquare
|
||||
|
||||
size() {
|
||||
>size : () => number
|
||||
|
||||
return 0;
|
||||
>0 : 0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/a.js(2,16): error TS1003: Identifier expected.
|
||||
|
||||
|
||||
==== /a.js (1 errors) ====
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements */
|
||||
|
||||
!!! error TS1003: Identifier expected.
|
||||
class B {
|
||||
}
|
||||
|
16
tests/baselines/reference/jsdocImplements_missingType.js
Normal file
16
tests/baselines/reference/jsdocImplements_missingType.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
//// [a.js]
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements */
|
||||
class B {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
declare class A {
|
||||
x: number;
|
||||
}
|
||||
/** @implements */
|
||||
declare class B {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
=== /a.js ===
|
||||
class A { constructor() { this.x = 0; } }
|
||||
>A : Symbol(A, Decl(a.js, 0, 0))
|
||||
>this.x : Symbol(A.x, Decl(a.js, 0, 25))
|
||||
>this : Symbol(A, Decl(a.js, 0, 0))
|
||||
>x : Symbol(A.x, Decl(a.js, 0, 25))
|
||||
|
||||
/** @implements */
|
||||
class B {
|
||||
>B : Symbol(B, Decl(a.js, 0, 41))
|
||||
}
|
||||
|
14
tests/baselines/reference/jsdocImplements_missingType.types
Normal file
14
tests/baselines/reference/jsdocImplements_missingType.types
Normal file
|
@ -0,0 +1,14 @@
|
|||
=== /a.js ===
|
||||
class A { constructor() { this.x = 0; } }
|
||||
>A : A
|
||||
>this.x = 0 : 0
|
||||
>this.x : number
|
||||
>this : this
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
/** @implements */
|
||||
class B {
|
||||
>B : B
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/a.js(3,7): error TS2720: Class 'B' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
|
||||
Property 'x' is missing in type 'B' but required in type 'A'.
|
||||
|
||||
|
||||
==== /a.js (1 errors) ====
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements A*/
|
||||
class B {}
|
||||
~
|
||||
!!! error TS2720: Class 'B' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
|
||||
!!! error TS2720: Property 'x' is missing in type 'B' but required in type 'A'.
|
||||
!!! related TS2728 /a.js:1:27: 'x' is declared here.
|
||||
|
||||
/** @implements A*/
|
||||
class B2 {
|
||||
x = 10
|
||||
}
|
||||
|
||||
/** @implements {A}*/
|
||||
class B3 {
|
||||
constructor() { this.x = 10 }
|
||||
}
|
||||
|
33
tests/baselines/reference/jsdocImplements_properties.js
Normal file
33
tests/baselines/reference/jsdocImplements_properties.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
//// [a.js]
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements A*/
|
||||
class B {}
|
||||
|
||||
/** @implements A*/
|
||||
class B2 {
|
||||
x = 10
|
||||
}
|
||||
|
||||
/** @implements {A}*/
|
||||
class B3 {
|
||||
constructor() { this.x = 10 }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
declare class A {
|
||||
x: number;
|
||||
}
|
||||
/** @implements A*/
|
||||
declare class B implements A {
|
||||
}
|
||||
/** @implements A*/
|
||||
declare class B2 implements A {
|
||||
x: number;
|
||||
}
|
||||
/** @implements {A}*/
|
||||
declare class B3 implements A {
|
||||
x: number;
|
||||
}
|
29
tests/baselines/reference/jsdocImplements_properties.symbols
Normal file
29
tests/baselines/reference/jsdocImplements_properties.symbols
Normal file
|
@ -0,0 +1,29 @@
|
|||
=== /a.js ===
|
||||
class A { constructor() { this.x = 0; } }
|
||||
>A : Symbol(A, Decl(a.js, 0, 0))
|
||||
>this.x : Symbol(A.x, Decl(a.js, 0, 25))
|
||||
>this : Symbol(A, Decl(a.js, 0, 0))
|
||||
>x : Symbol(A.x, Decl(a.js, 0, 25))
|
||||
|
||||
/** @implements A*/
|
||||
class B {}
|
||||
>B : Symbol(B, Decl(a.js, 0, 41))
|
||||
|
||||
/** @implements A*/
|
||||
class B2 {
|
||||
>B2 : Symbol(B2, Decl(a.js, 2, 10))
|
||||
|
||||
x = 10
|
||||
>x : Symbol(B2.x, Decl(a.js, 5, 10))
|
||||
}
|
||||
|
||||
/** @implements {A}*/
|
||||
class B3 {
|
||||
>B3 : Symbol(B3, Decl(a.js, 7, 1))
|
||||
|
||||
constructor() { this.x = 10 }
|
||||
>this.x : Symbol(B3.x, Decl(a.js, 11, 19))
|
||||
>this : Symbol(B3, Decl(a.js, 7, 1))
|
||||
>x : Symbol(B3.x, Decl(a.js, 11, 19))
|
||||
}
|
||||
|
34
tests/baselines/reference/jsdocImplements_properties.types
Normal file
34
tests/baselines/reference/jsdocImplements_properties.types
Normal file
|
@ -0,0 +1,34 @@
|
|||
=== /a.js ===
|
||||
class A { constructor() { this.x = 0; } }
|
||||
>A : A
|
||||
>this.x = 0 : 0
|
||||
>this.x : number
|
||||
>this : this
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
/** @implements A*/
|
||||
class B {}
|
||||
>B : B
|
||||
|
||||
/** @implements A*/
|
||||
class B2 {
|
||||
>B2 : B2
|
||||
|
||||
x = 10
|
||||
>x : number
|
||||
>10 : 10
|
||||
}
|
||||
|
||||
/** @implements {A}*/
|
||||
class B3 {
|
||||
>B3 : B3
|
||||
|
||||
constructor() { this.x = 10 }
|
||||
>this.x = 10 : 10
|
||||
>this.x : number
|
||||
>this : this
|
||||
>x : number
|
||||
>10 : 10
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/a.js(2,7): error TS2420: Class 'B' incorrectly implements interface 'Sig'.
|
||||
Index signature is missing in type 'B'.
|
||||
|
||||
|
||||
==== /defs.d.ts (0 errors) ====
|
||||
interface Sig {
|
||||
[index: string]: string
|
||||
}
|
||||
==== /a.js (1 errors) ====
|
||||
/** @implements {Sig} */
|
||||
class B {
|
||||
~
|
||||
!!! error TS2420: Class 'B' incorrectly implements interface 'Sig'.
|
||||
!!! error TS2420: Index signature is missing in type 'B'.
|
||||
}
|
||||
|
18
tests/baselines/reference/jsdocImplements_signatures.js
Normal file
18
tests/baselines/reference/jsdocImplements_signatures.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
//// [tests/cases/conformance/jsdoc/jsdocImplements_signatures.ts] ////
|
||||
|
||||
//// [defs.d.ts]
|
||||
interface Sig {
|
||||
[index: string]: string
|
||||
}
|
||||
//// [a.js]
|
||||
/** @implements {Sig} */
|
||||
class B {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
/** @implements {Sig} */
|
||||
declare class B implements Sig {
|
||||
}
|
13
tests/baselines/reference/jsdocImplements_signatures.symbols
Normal file
13
tests/baselines/reference/jsdocImplements_signatures.symbols
Normal file
|
@ -0,0 +1,13 @@
|
|||
=== /defs.d.ts ===
|
||||
interface Sig {
|
||||
>Sig : Symbol(Sig, Decl(defs.d.ts, 0, 0))
|
||||
|
||||
[index: string]: string
|
||||
>index : Symbol(index, Decl(defs.d.ts, 1, 5))
|
||||
}
|
||||
=== /a.js ===
|
||||
/** @implements {Sig} */
|
||||
class B {
|
||||
>B : Symbol(B, Decl(a.js, 0, 0))
|
||||
}
|
||||
|
11
tests/baselines/reference/jsdocImplements_signatures.types
Normal file
11
tests/baselines/reference/jsdocImplements_signatures.types
Normal file
|
@ -0,0 +1,11 @@
|
|||
=== /defs.d.ts ===
|
||||
interface Sig {
|
||||
[index: string]: string
|
||||
>index : string
|
||||
}
|
||||
=== /a.js ===
|
||||
/** @implements {Sig} */
|
||||
class B {
|
||||
>B : B
|
||||
}
|
||||
|
25
tests/cases/conformance/jsdoc/jsdocImplements_class.ts
Normal file
25
tests/cases/conformance/jsdoc/jsdocImplements_class.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /a.js
|
||||
class A {
|
||||
/** @return {number} */
|
||||
method() { throw new Error(); }
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B {
|
||||
method() { return 0 }
|
||||
}
|
||||
|
||||
/** @implements A */
|
||||
class B2 {
|
||||
/** @return {string} */
|
||||
method() { return "" }
|
||||
}
|
||||
|
||||
/** @implements {A} */
|
||||
class B3 {
|
||||
}
|
26
tests/cases/conformance/jsdoc/jsdocImplements_interface.ts
Normal file
26
tests/cases/conformance/jsdoc/jsdocImplements_interface.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /defs.d.ts
|
||||
interface A {
|
||||
mNumber(): number;
|
||||
}
|
||||
// @Filename: /a.js
|
||||
/** @implements A */
|
||||
class B {
|
||||
mNumber() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/** @implements {A} */
|
||||
class B2 {
|
||||
mNumber() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/** @implements A */
|
||||
class B3 {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /defs.d.ts
|
||||
interface Drawable {
|
||||
draw(): number;
|
||||
}
|
||||
interface Sizable {
|
||||
size(): number;
|
||||
}
|
||||
// @Filename: /a.js
|
||||
/**
|
||||
* @implements {Drawable}
|
||||
* @implements Sizable
|
||||
**/
|
||||
class Square {
|
||||
draw() {
|
||||
return 0;
|
||||
}
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @implements Drawable
|
||||
* @implements {Sizable}
|
||||
**/
|
||||
class BadSquare {
|
||||
size() {
|
||||
return 0;
|
||||
}
|
||||
}
|
11
tests/cases/conformance/jsdoc/jsdocImplements_missingType.ts
Normal file
11
tests/cases/conformance/jsdoc/jsdocImplements_missingType.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /a.js
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements */
|
||||
class B {
|
||||
}
|
20
tests/cases/conformance/jsdoc/jsdocImplements_properties.ts
Normal file
20
tests/cases/conformance/jsdoc/jsdocImplements_properties.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /a.js
|
||||
class A { constructor() { this.x = 0; } }
|
||||
/** @implements A*/
|
||||
class B {}
|
||||
|
||||
/** @implements A*/
|
||||
class B2 {
|
||||
x = 10
|
||||
}
|
||||
|
||||
/** @implements {A}*/
|
||||
class B3 {
|
||||
constructor() { this.x = 10 }
|
||||
}
|
14
tests/cases/conformance/jsdoc/jsdocImplements_signatures.ts
Normal file
14
tests/cases/conformance/jsdoc/jsdocImplements_signatures.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @declaration: true
|
||||
// @emitDeclarationOnly: true
|
||||
// @outDir: ./out
|
||||
|
||||
// @Filename: /defs.d.ts
|
||||
interface Sig {
|
||||
[index: string]: string
|
||||
}
|
||||
// @Filename: /a.js
|
||||
/** @implements {Sig} */
|
||||
class B {
|
||||
}
|
Loading…
Reference in a new issue