Skip to content

Commit e68dd64

Browse files
committed
[javascript mode] Improve TypeScript support
Add type conditionals, fix parenthesized types, support quoted property names, fix handling of type parameters in type definitions, and handle call signatures in interfaces and object types. Closes #5737
1 parent 74f3199 commit e68dd64

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

mode/javascript/javascript.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
376376
} else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
377377
cx.marked = "keyword"
378378
if (value == "enum") return cont(enumdef);
379-
else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
379+
else if (value == "type") return cont(typename, expect("operator"), typeexpr, expect(";"));
380380
else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
381381
} else if (isTS && value == "namespace") {
382382
cx.marked = "keyword"
@@ -574,7 +574,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
574574
}
575575
function maybetype(type, value) {
576576
if (isTS) {
577-
if (type == ":") return cont(typeexpr);
577+
if (type == ":" || value == "in") return cont(typeexpr);
578578
if (value == "?") return cont(maybetype);
579579
}
580580
}
@@ -591,9 +591,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
591591
}
592592
}
593593
function typeexpr(type, value) {
594-
if (value == "keyof" || value == "typeof") {
594+
if (value == "keyof" || value == "typeof" || value == "infer") {
595595
cx.marked = "keyword"
596-
return cont(value == "keyof" ? typeexpr : expressionNoComma)
596+
return cont(value == "typeof" ? expressionNoComma : typeexpr)
597597
}
598598
if (type == "variable" || value == "void") {
599599
cx.marked = "type"
@@ -602,7 +602,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
602602
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
603603
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
604604
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
605-
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
605+
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
606606
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
607607
}
608608
function maybeReturnType(type) {
@@ -612,26 +612,28 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
612612
if (type == "variable" || cx.style == "keyword") {
613613
cx.marked = "property"
614614
return cont(typeprop)
615-
} else if (value == "?") {
615+
} else if (value == "?" || type == "number" || type == "string") {
616616
return cont(typeprop)
617617
} else if (type == ":") {
618618
return cont(typeexpr)
619619
} else if (type == "[") {
620-
return cont(expression, maybetype, expect("]"), typeprop)
620+
return cont(expect("variable"), maybetype, expect("]"), typeprop)
621621
} else if (type == "(") {
622-
return cont(pushlex(")"), commasep(funarg, ")"), poplex, typeprop)
622+
return pass(functiondecl, typeprop)
623623
}
624624
}
625625
function typearg(type, value) {
626626
if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
627627
if (type == ":") return cont(typeexpr)
628+
if (type == "spread") return cont(typearg)
628629
return pass(typeexpr)
629630
}
630631
function afterType(type, value) {
631632
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
632633
if (value == "|" || type == "." || value == "&") return cont(typeexpr)
633-
if (type == "[") return cont(expect("]"), afterType)
634+
if (type == "[") return cont(typeexpr, expect("]"), afterType)
634635
if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
636+
if (value == "?") return cont(typeexpr, expect(":"), typeexpr)
635637
}
636638
function maybeTypeArgs(_, value) {
637639
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
@@ -710,6 +712,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
710712
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
711713
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl)
712714
}
715+
function typename(type, value) {
716+
if (type == "keyword" || type == "variable") {
717+
cx.marked = "type"
718+
return cont(typename)
719+
} else if (value == "<") {
720+
return cont(pushlex(">"), commasep(typeparam, ">"), poplex)
721+
}
722+
}
713723
function funarg(type, value) {
714724
if (value == "@") cont(expression, funarg)
715725
if (type == "spread") return cont(funarg);
@@ -744,12 +754,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
744754
cx.marked = "property";
745755
return cont(isTS ? classfield : functiondef, classBody);
746756
}
757+
if (type == "number" || type == "string") return cont(isTS ? classfield : functiondef, classBody);
747758
if (type == "[")
748759
return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
749760
if (value == "*") {
750761
cx.marked = "keyword";
751762
return cont(classBody);
752763
}
764+
if (isTS && type == "(") return pass(functiondecl, classBody)
753765
if (type == ";") return cont(classBody);
754766
if (type == "}") return cont();
755767
if (value == "@") return cont(expression, classBody)

0 commit comments

Comments
 (0)