Skip to content

Commit 409166d

Browse files
committed
Add generic type parameter to infer parameters
1 parent 00d2df3 commit 409166d

File tree

4 files changed

+80
-11
lines changed

4 files changed

+80
-11
lines changed

index.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
/**
2-
* @typedef {import('unist').Parent} Parent
3-
* @typedef {import('unist').Node} Node
4-
*
2+
* @typedef {import('unist').Parent} UnistParent
3+
* @typedef {import('unist').Node} UnistNode
4+
*/
5+
6+
/**
7+
* @template {UnistParent} Parent
58
* @callback Modifier
69
* Callback called for each `child` in `parent` later given to `modify`.
7-
* @param {Node} node
10+
* @param {Parent['children'][number]} node
811
* Child of `parent`.
912
* @param {number} index
1013
* Position of `child` in `parent`.
1114
* @param {Parent} parent
1215
* Parent node.
1316
* @returns {number|void}
1417
* Position to move to next.
15-
*
18+
*/
19+
20+
/**
21+
* @template {UnistParent} Parent
1622
* @callback Modify
1723
* Modify children of `parent`.
1824
* @param {Parent} node
@@ -27,15 +33,16 @@ import {arrayIterate} from 'array-iterate'
2733
* Wrap `modifier` to be called for each child in the nodes later given to
2834
* `modify`.
2935
*
30-
* @param {Modifier} modifier
36+
* @template {UnistParent} Parent
37+
* @param {Modifier<Parent>} modifier
3138
* Callback called for each `child` in `parent` later given to `modify`.
32-
* @returns {Modify}
39+
* @returns {Modify<Parent>}
3340
* Modify children of `parent`.
3441
*/
3542
export function modifyChildren(modifier) {
3643
return modify
3744

38-
/** @type {Modify} */
45+
/** @type {Modify<UnistParent>} */
3946
function modify(parent) {
4047
if (!parent || !parent.children) {
4148
throw new Error('Missing children in `parent` for `modifier`')
@@ -48,7 +55,7 @@ export function modifyChildren(modifier) {
4855
* Pass the context as the third argument to `modifier`.
4956
*
5057
* @this {Parent}
51-
* @param {Node} node
58+
* @param {UnistNode} node
5259
* @param {number} index
5360
*/
5461
function iteratee(node, index) {

index.test-d.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import {expectError, expectType} from 'tsd'
2+
import type {Node, Parent, Literal} from 'unist'
3+
import {modifyChildren} from './index.js'
4+
5+
/* eslint-disable @typescript-eslint/consistent-type-definitions */
6+
7+
/* Setup */
8+
const sampleTree: Root = {
9+
type: 'root',
10+
children: [{type: 'heading', depth: 1, children: []}]
11+
}
12+
13+
type Content = Flow | Phrasing
14+
15+
interface Root extends Parent {
16+
type: 'root'
17+
children: Flow[]
18+
}
19+
20+
type Flow = Blockquote | Heading | Paragraph
21+
22+
interface Blockquote extends Parent {
23+
type: 'blockquote'
24+
children: Flow[]
25+
}
26+
27+
interface Heading extends Parent {
28+
type: 'heading'
29+
depth: number
30+
children: Phrasing[]
31+
}
32+
33+
interface Paragraph extends Parent {
34+
type: 'paragraph'
35+
children: Phrasing[]
36+
}
37+
38+
type Phrasing = Text | Emphasis
39+
40+
interface Emphasis extends Parent {
41+
type: 'emphasis'
42+
children: Phrasing[]
43+
}
44+
45+
interface Text extends Literal {
46+
type: 'text'
47+
value: string
48+
}
49+
50+
/* Missing params. */
51+
expectError(modifyChildren())
52+
53+
modifyChildren((node, _, parent: Emphasis) => {
54+
expectType<Phrasing>(node)
55+
})
56+
57+
modifyChildren((node, _, parent: Root) => {
58+
expectType<Flow>(node)
59+
})
60+
61+
/* eslint-enable @typescript-eslint/consistent-type-definitions */

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@
4444
"remark-preset-wooorm": "^9.0.0",
4545
"rimraf": "^3.0.0",
4646
"tape": "^5.0.0",
47+
"tsd": "^0.24.0",
4748
"type-coverage": "^2.0.0",
4849
"typescript": "^4.0.0",
4950
"xo": "^0.52.0"
5051
},
5152
"scripts": {
5253
"prepack": "npm run build && npm run format",
53-
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
54+
"build": "rimraf \"*.d.ts\" && tsc && tsd && type-coverage",
5455
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5556
"test-api": "node test.js",
5657
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Call the bound [`modifier`][modifier] for each child in `parent`
123123
## Types
124124

125125
This package is fully typed with [TypeScript][].
126-
It exports the additional types `Modifier` and `Modify`.
126+
It exports the additional types `Modifier<Parent>` and `Modify<Parent>`.
127127

128128
## Compatibility
129129

0 commit comments

Comments
 (0)