add assertions signature for TypeScript (#10543)

* add asserts predicate

* fix flow

* babel-generator for typescript assertions

* babel-types for typescript assertions

* asserts modifier as boolean
This commit is contained in:
Tan Li Hau
2019-10-30 01:51:33 +08:00
committed by Nicolò Ribaudo
parent 4cd93ab5f3
commit 38a3063111
19 changed files with 1721 additions and 17 deletions

View File

@@ -904,21 +904,34 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const t: N.TsTypeAnnotation = this.startNode();
this.expect(returnToken);
const assertsModifier = this.tsTryParse(
this.tsParseTypePredicateAssertsModifier.bind(this),
);
const typePredicateVariable =
this.tsIsIdentifier() &&
this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this));
if (!typePredicateVariable) {
return this.tsParseTypeAnnotation(/* eatColon */ false, t);
if (!assertsModifier) {
// : type
return this.tsParseTypeAnnotation(/* eatColon */ false, t);
}
// : asserts foo
const node = this.startNodeAtNode(t);
node.parameterName = this.parseIdentifier();
node.assertsModifier = assertsModifier;
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
return this.finishNode(t, "TSTypeAnnotation");
}
// : foo is type
const type = this.tsParseTypeAnnotation(/* eatColon */ false);
const node: N.TsTypePredicate = this.startNodeAtNode(
typePredicateVariable,
);
const node = this.startNodeAtNode(t);
node.parameterName = typePredicateVariable;
node.typeAnnotation = type;
node.assertsModifier = assertsModifier;
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
return this.finishNode(t, "TSTypeAnnotation");
});
@@ -946,6 +959,23 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}
tsParseTypePredicateAssertsModifier(): boolean {
if (!this.tsIsIdentifier()) {
return false;
}
const id = this.parseIdentifier();
if (
id.name !== "asserts" ||
this.hasPrecedingLineBreak() ||
!this.tsIsIdentifier()
) {
return false;
}
return true;
}
tsParseTypeAnnotation(
eatColon = true,
t: N.TsTypeAnnotation = this.startNode(),