fix(ts): raise error for export default interface {} (#13622)

This commit is contained in:
Oleksandr T 2021-08-02 19:16:01 +03:00 committed by GitHub
parent 86fae72e5b
commit b3ab4769d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 13 deletions

View File

@ -107,6 +107,8 @@ const TSErrors = makeErrorTemplates(
InvalidModifiersOrder: "'%0' modifier must precede '%1' modifier.", InvalidModifiersOrder: "'%0' modifier must precede '%1' modifier.",
InvalidTupleMemberLabel: InvalidTupleMemberLabel:
"Tuple members must be labeled with a simple identifier.", "Tuple members must be labeled with a simple identifier.",
MissingInterfaceName:
"'interface' declarations must be followed by an identifier.",
MixedLabeledAndUnlabeledElements: MixedLabeledAndUnlabeledElements:
"Tuple members must all have names or all not have names.", "Tuple members must all have names or all not have names.",
NonAbstractClassHasAbstractMethod: NonAbstractClassHasAbstractMethod:
@ -1419,12 +1421,18 @@ export default (superClass: Class<Parser>): Class<Parser> =>
tsParseInterfaceDeclaration( tsParseInterfaceDeclaration(
node: N.TsInterfaceDeclaration, node: N.TsInterfaceDeclaration,
): N.TsInterfaceDeclaration { ): N.TsInterfaceDeclaration {
node.id = this.parseIdentifier(); if (this.match(tt.name)) {
this.checkLVal( node.id = this.parseIdentifier();
node.id, this.checkLVal(
"typescript interface declaration", node.id,
BIND_TS_INTERFACE, "typescript interface declaration",
); BIND_TS_INTERFACE,
);
} else {
node.id = null;
this.raise(this.state.start, TSErrors.MissingInterfaceName);
}
node.typeParameters = this.tsTryParseTypeParameters(); node.typeParameters = this.tsTryParseTypeParameters();
if (this.eat(tt._extends)) { if (this.eat(tt._extends)) {
node.extends = this.tsParseHeritageClause("extends"); node.extends = this.tsParseHeritageClause("extends");
@ -2305,12 +2313,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// export default interface allowed in: // export default interface allowed in:
// https://github.com/Microsoft/TypeScript/pull/16040 // https://github.com/Microsoft/TypeScript/pull/16040
if (this.state.value === "interface") { if (this.state.value === "interface") {
const result = this.tsParseDeclaration( const interfaceNode = this.startNode();
this.startNode(), this.next();
this.state.value, const result = this.tsParseInterfaceDeclaration(interfaceNode);
true,
);
if (result) return result; if (result) return result;
} }

View File

@ -1481,7 +1481,7 @@ export type TsImportType = TsTypeBase & {
export type TsInterfaceDeclaration = DeclarationBase & { export type TsInterfaceDeclaration = DeclarationBase & {
type: "TSInterfaceDeclaration", type: "TSInterfaceDeclaration",
id: Identifier, id: ?Identifier,
typeParameters: ?TsTypeParameterDeclaration, typeParameters: ?TsTypeParameterDeclaration,
// TS uses "heritageClauses", but want this to resemble ClassBase. // TS uses "heritageClauses", but want this to resemble ClassBase.
extends?: $ReadOnlyArray<TsExpressionWithTypeArguments>, extends?: $ReadOnlyArray<TsExpressionWithTypeArguments>,

View File

@ -0,0 +1 @@
export default interface {}

View File

@ -0,0 +1,31 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"errors": [
"SyntaxError: 'interface' declarations must be followed by an identifier. (1:25)"
],
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExportDefaultDeclaration",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"exportKind": "value",
"declaration": {
"type": "TSInterfaceDeclaration",
"start":15,"end":27,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":27}},
"id": null,
"body": {
"type": "TSInterfaceBody",
"start":25,"end":27,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":27}},
"body": []
}
}
}
],
"directives": []
}
}