@@ -7,6 +7,13 @@ https://github.com/ast-grep/ast-grep/issues/48
77
88It guides one to write comprehensive AST code (in case people forget to handle some cases)
99
10+ # What are good TypeScript types?
11+
12+ * Correct: reject invalid code and accept valid code
13+ * Concise: easy to read, especially in hover and completion
14+ * Robust: easy to refactor
15+ * Performant: fast to compile
16+
1017# TreeSitter's types
1118
1219Tree-Sitter's official API is untyped. However it provides static node types in json
@@ -33,36 +40,72 @@ For example `+`/`-`/`*`/`/` is too noisy for a general AST library
3340
3441Use type script to resolve type alias
3542
36- ## ` NodeKinds <M>`
43+ ## ` Kinds <M>`
3744
38- 1 . string literal completion with string
45+ 1 . string literal completion with ` LowPriorityString `
39462 . lenient
4047
4148Problem?
4249
4350https://github.com/microsoft/TypeScript/issues/33471
4451https://github.com/microsoft/TypeScript/issues/26277
4552
46- ## Distinguish general ` string ` and specific kinds
47- ` RefinedNode<> `
53+ ## Distinguish general ` string ` ly kinds and specific kinds
54+
55+ Note ` SgNode<'expression' | 'type'> ` is different from ` SgNode<'expression'> | SgNode<'type'> `
56+
57+ ast-grep uses a trick via the type ` RefineNode<> ` to let you switch between the two
4858
4959
5060## Refine Node, Manually
5161
52621.via ` sgNode.find<"KIND"> `
53632.via ` sgNode.is<"KIND"> ` , One time type narrowing
5464
65+ Using the intersting overloading feature of TypeScript
66+
67+ ``` typescript
68+ interface NodeMethod <K > {
69+ (): SgNode
70+ <T extends K >(): SgNode <T >
71+ }
72+ ```
73+
5574## Refine Node, Automatically
5675
57- ` sgNode.field("kind") `
76+ ` sgNode.field("kind") ` will
77+
5878
79+ ## Exhaustive Checking via ` sgNode.kindToRefine `
5980
60- ## Exhaustive Checking via ` sgNode.kindForRefinement `
81+ Only available for node with specific kinds
6182
62- Only available specific kinds
83+ ``` typescript
84+ const func: SgNode <' function_declaration' > | SgNode <' arrow_function' >
85+
86+ switch (func .kindToRefine ) {
87+ case ' function_declaration' :
88+ func .kindToRefine // narrow to 'function_declaration'
89+ break
90+ case ' arrow_function' :
91+ func .kindToRefine // narrow to 'arrow_function'
92+ break
93+ default :
94+ func satisfies never // exhaustive check!
95+ }
96+ ```
6397
6498## Typed Rule!
6599
100+ ``` typescript
101+ sgNode .find ({
102+ rule: {
103+ // kind: 'invalid_kind', // error!
104+ kind: ' function_declaration' , // typed!
105+ }
106+ })
107+ ```
108+
66109## Opt-in refinement for better compile time performance
67110
68111# Ending
0 commit comments