Skip to content

Commit 3e83446

Browse files
committed
Support predefined types in type predicates
In `function (): object {...}` object is a predefined type, but in `function (object: any): object is foo{}` object is now a regular identifier. The previous grammar was not able to parse the second example, probably because when the parsers sees the second ':' for the return type, the contextual lexual does not know yet if it's a type predicate or predefined type, so it accepts 'object' as a predefined type and only fail later when it sees 'is'. test plan: I tried in astexplorer.net and the second example is valid typescript code (sadly).
1 parent 1b3ba31 commit 3e83446

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

common/corpus/types.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,30 @@ function isT(t: T): t is T {
876876
(type_identifier)))
877877
(statement_block (return_statement (true)))))
878878

879+
==================================
880+
Type predicate and predefined types
881+
==================================
882+
883+
function isFish(pet: Fish): pet is Fish {
884+
}
885+
886+
function isFish(object: Fish): object is Fish {
887+
}
888+
889+
---
890+
(program
891+
(function_declaration (identifier)
892+
(formal_parameters
893+
(required_parameter (identifier) (type_annotation (type_identifier))))
894+
(type_predicate_annotation (type_predicate (identifier) (type_identifier)))
895+
(statement_block))
896+
(function_declaration (identifier)
897+
(formal_parameters
898+
(required_parameter (identifier) (type_annotation (type_identifier))))
899+
(type_predicate_annotation (type_predicate (identifier) (type_identifier)))
900+
(statement_block))
901+
)
902+
879903
==================================
880904
Read-only arrays
881905
==================================

common/define-grammar.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,16 @@ module.exports = function defineGrammar(dialect) {
686686
)),
687687

688688
type_predicate: $ => seq(
689-
field('name', choice($.identifier, $.this)),
689+
field('name', choice(
690+
$.identifier,
691+
$.this,
692+
// Sometimes tree-sitter contextual lexing is not good enough to know
693+
// that 'object' in ':object is foo' is really an identifier and not
694+
// a predefined_type, so we must explicitely list all possibilities.
695+
// TODO: should we use '_reserved_identifier'? Should all the element in
696+
// 'predefined_type' be added to '_reserved_identifier'?
697+
alias($.predefined_type, $.identifier)
698+
)),
690699
'is',
691700
field('type', $._type)
692701
),

0 commit comments

Comments
 (0)