Skip to content

Commit a8f3bda

Browse files
authored
Add JSDoc based types
Closes GH-6. Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com> Reviewed-by: Remco Haszing <remcohaszing@gmail.com>
1 parent b4ff923 commit a8f3bda

File tree

9 files changed

+106
-133
lines changed

9 files changed

+106
-133
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
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

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,46 @@
1-
export function u(type, props, value) {
2-
var node = {type: String(type)}
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist').Parent} Parent
4+
* @typedef {import('unist').Literal} Literal
5+
* @typedef {Object.<string, unknown>} Props
6+
* @typedef {Array.<Node>|string} ChildrenOrValue
7+
*
8+
* @typedef {(<T extends string, P extends Record<string, unknown>, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps
9+
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps
10+
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps
11+
* @typedef {(<T extends string, C extends Node[]>(type: T, children: C) => {type: T, children: C})} BuildParent
12+
* @typedef {(<T extends string>(type: T, value: string) => {type: T, value: string})} BuildLiteral
13+
* @typedef {(<T extends string>(type: T) => {type: T})} BuildVoid
14+
*/
315

4-
if (
5-
(value === undefined || value === null) &&
6-
(typeof props !== 'object' || Array.isArray(props))
7-
) {
8-
value = props
9-
} else {
10-
Object.assign(node, props)
11-
}
16+
export var u = /**
17+
* @type {BuildVoid & BuildVoidWithProps & BuildLiteral & BuildLiteralWithProps & BuildParent & BuildParentWithProps}
18+
*/ (
19+
/**
20+
* @param {string} type Type of node
21+
* @param {Props|ChildrenOrValue} [props] Additional properties for node (or `children` or `value`)
22+
* @param {ChildrenOrValue} [value] `children` or `value` of node
23+
* @returns {Node}
24+
*/
25+
function (type, props, value) {
26+
/** @type {Node} */
27+
var node = {type: String(type)}
1228

13-
if (Array.isArray(value)) {
14-
node.children = value
15-
} else if (value !== undefined && value !== null) {
16-
node.value = String(value)
17-
}
29+
if (
30+
(value === undefined || value === null) &&
31+
(typeof props === 'string' || Array.isArray(props))
32+
) {
33+
value = props
34+
} else {
35+
Object.assign(node, props)
36+
}
1837

19-
return node
20-
}
38+
if (Array.isArray(value)) {
39+
node.children = value
40+
} else if (value !== undefined && value !== null) {
41+
node.value = String(value)
42+
}
43+
44+
return node
45+
}
46+
)

index.test-d.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {expectType, expectAssignable} from 'tsd'
2+
import {Text, List, ListItem, HTML} from 'mdast'
3+
import {u} from './index.js'
4+
5+
expectType<{type: 'example'}>(u('example'))
6+
expectType<{type: 'example'} & {property: true}>(u('example', {property: true}))
7+
8+
const node1 = u('text', 'text')
9+
10+
expectType<{type: 'text'; value: string}>(node1)
11+
expectAssignable<Text>(node1)
12+
13+
const node2 = u('list', [
14+
u('listItem', [u('html', {checked: true}, '<strong>text</strong>')])
15+
])
16+
17+
expectType<{
18+
type: 'list'
19+
children: Array<{
20+
type: 'listItem'
21+
children: Array<{type: 'html'; value: string} & {checked: boolean}>
22+
}>
23+
}>(node2)
24+
expectAssignable<List>(node2)
25+
expectAssignable<ListItem>(node2.children[0])
26+
expectAssignable<HTML>(node2.children[0].children[0])

package.json

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,35 @@
3333
"sideEffects": false,
3434
"type": "module",
3535
"main": "index.js",
36-
"types": "types/index.d.ts",
36+
"types": "index.d.ts",
3737
"files": [
38-
"index.js",
39-
"types/index.d.ts"
38+
"index.d.ts",
39+
"index.js"
4040
],
41+
"dependencies": {
42+
"@types/unist": "^2.0.0"
43+
},
4144
"devDependencies": {
4245
"@types/mdast": "^3.0.0",
46+
"@types/tape": "^4.0.0",
4347
"c8": "^7.0.0",
44-
"dtslint": "^4.0.0",
4548
"prettier": "^2.0.0",
4649
"remark-cli": "^9.0.0",
4750
"remark-preset-wooorm": "^8.0.0",
51+
"rimraf": "^3.0.0",
4852
"tape": "^5.0.0",
53+
"tsd": "^0.14.0",
54+
"type-coverage": "^2.0.0",
55+
"typescript": "^4.0.0",
4956
"xo": "^0.38.0"
5057
},
5158
"scripts": {
59+
"prepack": "npm run build && npm run format",
60+
"build": "rimraf \"*.d.ts\" && tsc && tsd && type-coverage",
5261
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5362
"test-api": "node test.js",
5463
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
55-
"test-types": "dtslint types",
56-
"test": "npm run format && npm run test-coverage && npm run test-types"
64+
"test": "npm run build && npm run format && npm run test-coverage"
5765
},
5866
"prettier": {
5967
"tabWidth": 2,
@@ -66,6 +74,8 @@
6674
"xo": {
6775
"prettier": true,
6876
"rules": {
77+
"capitalized-comments": "off",
78+
"import/no-mutable-exports": "off",
6979
"no-var": "off",
7080
"prefer-arrow-callback": "off"
7181
}
@@ -74,5 +84,10 @@
7484
"plugins": [
7585
"preset-wooorm"
7686
]
87+
},
88+
"typeCoverage": {
89+
"atLeast": 100,
90+
"detail": true,
91+
"strict": true
7792
}
7893
}

tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"include": ["*.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+
}

types/index.d.ts

Lines changed: 0 additions & 77 deletions
This file was deleted.

types/tsconfig.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

types/tslint.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

types/unist-builder-tests.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)