Skip to content

Commit 3b30e6f

Browse files
committed
Add JSDoc based types
1 parent aa9a140 commit 3b30e6f

File tree

5 files changed

+141
-3
lines changed

5 files changed

+141
-3
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
*.d.ts
23
*.log
34
coverage/
45
node_modules/

index.js

+90-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
/**
2+
* @typedef {Parent['children'][number]|Root} Node
3+
* @typedef {import('mdast').Parent} Parent
4+
* @typedef {import('mdast').Literal} Literal
5+
* @typedef {import('mdast').Root} Root
6+
* @typedef {import('mdast').List} List
7+
* @typedef {import('mdast').ListItem} ListItem
8+
* @typedef {import('mdast').Heading} Heading
9+
* @typedef {import('mdast').Code} Code
10+
* @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition
11+
* @typedef {import('mdast').Definition} Definition
12+
* @typedef {import('mdast').Link} Link
13+
* @typedef {import('mdast').Image} Image
14+
* @typedef {import('mdast').LinkReference} LinkReference
15+
* @typedef {import('mdast').ImageReference} ImageReference
16+
* @typedef {import('mdast').FootnoteReference} FootnoteReference
17+
* @typedef {import('mdast').Table} Table
18+
*/
19+
120
import nodeAssert from 'assert'
221
import {zwitch} from 'zwitch'
322
import {mapz} from 'mapz'
@@ -85,10 +104,19 @@ var mdast = zwitch('type', {
85104

86105
var all = mapz(mdast, {key: 'children'})
87106

107+
/**
108+
* @param {unknown} node
109+
* @param {Parent} [ancestor]
110+
* @returns {asserts node is Node}
111+
*/
88112
function unknown(node, ancestor) {
89113
unistAssert(node, ancestor)
90114
}
91115

116+
/**
117+
* @param {unknown} node
118+
* @returns {asserts node is Parent}
119+
*/
92120
function assertParent(node) {
93121
unistParent(node)
94122
all(node)
@@ -107,12 +135,21 @@ function assertLiteral(node) {
107135
)
108136
}
109137

138+
/**
139+
* @param {unknown} node
140+
* @param {Parent} ancestor
141+
* @returns {asserts node is Root}
142+
*/
110143
function root(node, ancestor) {
111144
parent(node)
112145

113146
nodeAssert.strictEqual(ancestor, undefined, '`root` should not have a parent')
114147
}
115148

149+
/**
150+
* @param {unknown} node
151+
* @returns {asserts node is List}
152+
*/
116153
function list(node) {
117154
parent(node)
118155

@@ -144,6 +181,10 @@ function list(node) {
144181
}
145182
}
146183

184+
/**
185+
* @param {unknown} node
186+
* @returns {asserts node is ListItem}
187+
*/
147188
function listItem(node) {
148189
parent(node)
149190

@@ -164,13 +205,21 @@ function listItem(node) {
164205
}
165206
}
166207

208+
/**
209+
* @param {unknown} node
210+
* @returns {asserts node is Heading}
211+
*/
167212
function heading(node) {
168213
parent(node)
169214

170215
nodeAssert.ok(node.depth > 0, '`depth` should be gte `1`')
171216
nodeAssert.ok(node.depth <= 6, '`depth` should be lte `6`')
172217
}
173218

219+
/**
220+
* @param {unknown} node
221+
* @returns {asserts node is Code}
222+
*/
174223
function code(node) {
175224
literal(node)
176225

@@ -192,6 +241,10 @@ function code(node) {
192241
}
193242
}
194243

244+
/**
245+
* @param {unknown} node
246+
* @returns {asserts node is FootnoteDefinition}
247+
*/
195248
function footnoteDefinition(node) {
196249
parent(node)
197250

@@ -210,6 +263,10 @@ function footnoteDefinition(node) {
210263
}
211264
}
212265

266+
/**
267+
* @param {unknown} node
268+
* @returns {asserts node is Definition}
269+
*/
213270
function definition(node) {
214271
_void(node)
215272

@@ -238,6 +295,10 @@ function definition(node) {
238295
}
239296
}
240297

298+
/**
299+
* @param {unknown} node
300+
* @returns {asserts node is Link}
301+
*/
241302
function link(node) {
242303
parent(node)
243304

@@ -252,6 +313,10 @@ function link(node) {
252313
}
253314
}
254315

316+
/**
317+
* @param {unknown} node
318+
* @returns {asserts node is Image}
319+
*/
255320
function image(node) {
256321
_void(node)
257322

@@ -270,6 +335,10 @@ function image(node) {
270335
}
271336
}
272337

338+
/**
339+
* @param {unknown} node
340+
* @returns {asserts node is LinkReference}
341+
*/
273342
function linkReference(node) {
274343
parent(node)
275344

@@ -289,13 +358,18 @@ function linkReference(node) {
289358

290359
if (node.referenceType != null) {
291360
nodeAssert.notStrictEqual(
361+
// @ts-expect-error Check if it’s a string.
292362
['shortcut', 'collapsed', 'full'].indexOf(node.referenceType),
293363
-1,
294364
'`referenceType` must be `shortcut`, `collapsed`, or `full`'
295365
)
296366
}
297367
}
298368

369+
/**
370+
* @param {unknown} node
371+
* @returns {asserts node is ImageReference}
372+
*/
299373
function imageReference(node) {
300374
_void(node)
301375

@@ -319,13 +393,18 @@ function imageReference(node) {
319393

320394
if (node.referenceType != null) {
321395
nodeAssert.notStrictEqual(
396+
// @ts-expect-error Check if it’s a string.
322397
['shortcut', 'collapsed', 'full'].indexOf(node.referenceType),
323398
-1,
324399
'`referenceType` must be `shortcut`, `collapsed`, or `full`'
325400
)
326401
}
327402
}
328403

404+
/**
405+
* @param {unknown} node
406+
* @returns {asserts node is FootnoteReference}
407+
*/
329408
function footnoteReference(node) {
330409
_void(node)
331410

@@ -344,20 +423,29 @@ function footnoteReference(node) {
344423
}
345424
}
346425

426+
/**
427+
* @param {unknown} node
428+
* @returns {asserts node is Table}
429+
*/
347430
function table(node) {
348431
var index = -1
432+
/** @type {Array.<unknown>} */
433+
var align
434+
/** @type {unknown} */
349435
var value
350436

351437
parent(node)
352438

353439
if (node.align != null) {
354440
nodeAssert.ok(Array.isArray(node.align), '`align` must be `array`')
441+
align = node.align // type-coverage:ignore-line
355442

356-
while (++index < node.align.length) {
357-
value = node.align[index]
443+
while (++index < align.length) {
444+
value = align[index]
358445

359446
if (value != null) {
360447
nodeAssert.notStrictEqual(
448+
// @ts-expect-error Check if it’s a string.
361449
['left', 'right', 'center'].indexOf(value),
362450
-1,
363451
"each align in table must be `null, 'left', 'right', 'center'`"

index.test-d.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {expectType, expectNotType} from 'tsd'
2+
import {Parent} from 'mdast'
3+
import {Node, assert, parent} from './index.js'
4+
5+
var emptyNode = {type: 'doctype'}
6+
var literalNode = {type: 'text', value: 'a'}
7+
var parentNode = {type: 'element', children: [emptyNode, literalNode]}
8+
9+
expectNotType<Node>(emptyNode)
10+
expectNotType<Node>(literalNode)
11+
expectNotType<Node>(parentNode)
12+
13+
assert(emptyNode)
14+
expectType<Node>(emptyNode)
15+
16+
expectNotType<Parent>(parentNode)
17+
parent(parentNode)
18+
expectType<Parent>(parentNode)

package.json

+17-1
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,37 @@
2626
"sideEffects": false,
2727
"type": "module",
2828
"main": "index.js",
29+
"types": "index.d.ts",
2930
"files": [
31+
"index.d.ts",
3032
"index.js"
3133
],
3234
"dependencies": {
35+
"@types/mdast": "^3.0.3",
3336
"mapz": "^2.0.0",
3437
"unist-util-assert": "^3.0.0",
3538
"zwitch": "^2.0.0"
3639
},
3740
"devDependencies": {
41+
"@types/tape": "^4.0.0",
3842
"c8": "^7.0.0",
3943
"prettier": "^2.0.0",
4044
"remark-cli": "^9.0.0",
4145
"remark-preset-wooorm": "^8.0.0",
46+
"rimraf": "^3.0.0",
4247
"tape": "^5.0.0",
48+
"tsd": "^0.14.0",
49+
"type-coverage": "^2.0.0",
50+
"typescript": "^4.0.0",
4351
"xo": "^0.39.0"
4452
},
4553
"scripts": {
54+
"prepack": "npm run build && npm run format",
55+
"build": "rimraf \"{test/**,}*.d.ts\" && tsc && tsd && type-coverage",
4656
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
4757
"test-api": "node test/index.js",
4858
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
49-
"test": "npm run format && npm run build && npm run test-coverage"
59+
"test": "npm run build && npm run format && npm run build && npm run test-coverage"
5060
},
5161
"prettier": {
5262
"tabWidth": 2,
@@ -59,6 +69,7 @@
5969
"xo": {
6070
"prettier": true,
6171
"rules": {
72+
"capitalized-comments": "off",
6273
"eqeqeq": "off",
6374
"no-eq-null": "off",
6475
"no-var": "off",
@@ -69,5 +80,10 @@
6980
"plugins": [
7081
"preset-wooorm"
7182
]
83+
},
84+
"typeCoverage": {
85+
"atLeast": 100,
86+
"detail": true,
87+
"strict": true
7288
}
7389
}

tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"include": ["*.js", "test/**/*.js"],
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"module": "ES2020",
7+
"moduleResolution": "node",
8+
"allowJs": true,
9+
"checkJs": true,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
"allowSyntheticDefaultImports": true,
13+
"skipLibCheck": true
14+
}
15+
}

0 commit comments

Comments
 (0)