Skip to content

Commit 833e61e

Browse files
add more explanation
1 parent ebd6a70 commit 833e61e

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

website/blog/typed-napi.md

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ https://github.com/ast-grep/ast-grep/issues/48
77

88
It 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

1219
Tree-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

3441
Use 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`
3946
2. lenient
4047

4148
Problem?
4249

4350
https://github.com/microsoft/TypeScript/issues/33471
4451
https://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

5262
1.via `sgNode.find<"KIND">`
5363
2.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

Comments
 (0)