Skip to content

Commit 5573ee5

Browse files
committed
Refactor code-style
1 parent 5cd08f8 commit 5573ee5

16 files changed

+447
-372
lines changed

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
2-
* @typedef {import('./lib/index.js').Child} Child
32
* @typedef {import('./lib/index.js').Attributes} Attributes
3+
* @typedef {import('./lib/index.js').Child} Child
44
* @typedef {import('./lib/index.js').Result} Result
55
*/
66

jsx-runtime.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* @typedef {import('./lib/runtime.js').JSXProps}} JSXProps
2+
* @typedef {import('./lib/runtime.js').JSXProps} JSXProps
33
*/
44

55
// Export `JSX` as a global for TypeScript.
66
export * from './lib/jsx-automatic.js'
77

8-
export {jsx, jsxs, Fragment} from './lib/runtime.js'
8+
export {Fragment, jsx, jsxs} from './lib/runtime.js'

lib/index.js

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
/**
2-
* @typedef {import('xast').Root} Root
32
* @typedef {import('xast').Element} Element
3+
* @typedef {import('xast').Nodes} Nodes
4+
* @typedef {import('xast').Root} Root
45
*/
56

67
/**
7-
* @typedef {Root['children'][number]} Content
8-
* @typedef {Content | Root} Node
9-
* Any concrete `xast` node.
10-
*
11-
* @typedef {Root | Element} Result
8+
* @typedef {Element | Root} Result
129
* Result from a `x` call.
1310
*
14-
* @typedef {string | number | boolean | null | undefined} Value
11+
* @typedef {boolean | number | string | null | undefined} Value
1512
* Attribute value
13+
*
1614
* @typedef {{[attribute: string]: Value}} Attributes
1715
* Acceptable value for element properties.
1816
*
19-
* @typedef {string | number | null | undefined} PrimitiveChild
17+
* @typedef {boolean | number | string | null | undefined} PrimitiveChild
2018
* Primitive children, either ignored (nullish), or turned into text nodes.
21-
* @typedef {Array<Node | PrimitiveChild>} ArrayChild
19+
* @typedef {Array<Nodes | PrimitiveChild>} ArrayChild
2220
* List of children.
23-
* @typedef {Node | PrimitiveChild | ArrayChild} Child
21+
* @typedef {Nodes | PrimitiveChild | ArrayChild} Child
2422
* Acceptable child value.
25-
*
23+
*/
24+
25+
// Define JSX.
26+
27+
/**
2628
* @typedef {import('./jsx-classic.js').Element} x.JSX.Element
2729
* @typedef {import('./jsx-classic.js').IntrinsicAttributes} x.JSX.IntrinsicAttributes
2830
* @typedef {import('./jsx-classic.js').IntrinsicElements} x.JSX.IntrinsicElements
@@ -39,13 +41,14 @@
3941
* When string, an `Element` is built.
4042
* When nullish, a `Root` is built instead.
4143
* @param attributes
42-
* Attributes of the element.
44+
* Attributes of the element or first child.
4345
* @param children
4446
* Children of the node.
4547
* @returns
4648
* `Element` or `Root`.
4749
*/
4850
export const x =
51+
// Note: not yet possible to use the spread `...children` in JSDoc overloads.
4952
/**
5053
* @type {{
5154
* (): Root
@@ -68,7 +71,7 @@ export const x =
6871

6972
if (name === undefined || name === null) {
7073
node = {type: 'root', children: []}
71-
// @ts-expect-error Root builder doesn’t accept attributes.
74+
// @ts-expect-error: Root builder doesn’t accept attributes.
7275
children.unshift(attributes)
7376
} else if (typeof name === 'string') {
7477
node = {type: 'element', name, attributes: {}, children: []}
@@ -111,7 +114,7 @@ export const x =
111114
* List of nodes.
112115
* @param {Child} value
113116
* Child.
114-
* @returns {void}
117+
* @returns {undefined}
115118
* Nothing.
116119
*/
117120
function addChild(nodes, value) {

lib/jsx-automatic.d.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
/* eslint-disable-next-line @typescript-eslint/consistent-type-imports -- fix in major */
2-
import {Attributes, Child, Result} from './index.js'
1+
import type {Attributes, Child, Result} from './index.js'
32

43
export namespace JSX {
54
/**
@@ -12,16 +11,13 @@ export namespace JSX {
1211
*/
1312
type IntrinsicAttributes = never
1413

15-
/* eslint-disable @typescript-eslint/consistent-type-definitions -- interfaces are required here */
16-
1714
/**
1815
* This defines the prop types for known elements.
1916
*
2017
* For `xastscript` this defines any string may be used in combination with `xast` `Attributes`.
2118
*
2219
* This **must** be an interface.
2320
*/
24-
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
2521
interface IntrinsicElements {
2622
[name: string]:
2723
| Attributes
@@ -42,6 +38,4 @@ export namespace JSX {
4238
*/
4339
children?: never
4440
}
45-
46-
/* eslint-enable @typescript-eslint/consistent-type-definitions */
4741
}

lib/jsx-classic.d.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
/* eslint-disable-next-line @typescript-eslint/consistent-type-imports -- fix in major */
2-
import {Attributes, Child, Result} from './index.js'
1+
import type {Attributes, Child, Result} from './index.js'
32

43
/**
54
* This unique symbol is declared to specify the key on which JSX children are passed, without conflicting
@@ -17,16 +16,13 @@ export type Element = Result
1716
*/
1817
export type IntrinsicAttributes = never
1918

20-
/* eslint-disable @typescript-eslint/consistent-type-definitions -- interfaces are required here */
21-
2219
/**
2320
* This defines the prop types for known elements.
2421
*
2522
* For `xastscript` this defines any string may be used in combination with `xast` `Attributes`.
2623
*
2724
* This **must** be an interface.
2825
*/
29-
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
3026
export interface IntrinsicElements {
3127
[name: string]:
3228
| Attributes
@@ -47,5 +43,3 @@ export interface ElementChildrenAttribute {
4743
*/
4844
[children]?: never
4945
}
50-
51-
/* eslint-enable @typescript-eslint/consistent-type-definitions */

lib/runtime.js

+30-25
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
/**
2+
* @typedef {import('./index.js').Child} Child
23
* @typedef {import('./index.js').Element} Element
34
* @typedef {import('./index.js').Root} Root
4-
* @typedef {import('./index.js').Result} Result
5-
* @typedef {import('./index.js').Child} Child
6-
* @typedef {import('./index.js').Attributes} Attributes
75
* @typedef {import('./index.js').Value} Value
8-
*
9-
* @typedef {{[x: string]: Value | Child}} JSXProps
6+
*/
7+
8+
/**
9+
* @typedef {{[x: string]: Child | Value}} JSXProps
1010
*/
1111

1212
import {x} from './index.js'
1313

1414
/**
1515
* Create XML trees in xast through JSX.
1616
*
17-
* @param name
17+
* @overload
18+
* @param {null} name
19+
* @param {{children?: Child}} props
20+
* @param {string} [key]
21+
* @returns {Root}
22+
*
23+
* @overload
24+
* @param {string} name
25+
* @param {JSXProps} props
26+
* @param {string} [key]
27+
* @returns {Element}
28+
*
29+
* @param {string | null} name
1830
* Qualified name.
1931
*
2032
* Case sensitive and can contain a namespace prefix (such as `rdf:RDF`).
2133
* When string, an `Element` is built.
2234
* When nullish, a `Root` is built instead.
23-
* @param props
35+
* @param {JSXProps} props
2436
* Map of attributes.
2537
*
2638
* Nullish (`null` or `undefined`) or `NaN` values are ignored, other values
@@ -29,25 +41,18 @@ import {x} from './index.js'
2941
* Cannot be given if building a `Root`.
3042
* Cannot be omitted when building an `Element` if the first child is a
3143
* `Node`.
44+
* @param {string | null | undefined} [_key]
45+
* Key (not used).
46+
* @returns {Element | Root}
47+
* Result.
3248
*/
33-
export const jsx =
34-
/**
35-
* @type {{
36-
* (name: null | undefined, props: {children?: Child}, key?: string): Root
37-
* (name: string, props: JSXProps, key?: string): Element
38-
* }}
39-
*/
40-
(
41-
/**
42-
* @param {string | null} name
43-
* @param {Attributes & {children?: Child}} props
44-
* @returns {Result}
45-
*/
46-
function (name, props) {
47-
const {children, ...properties} = props
48-
return name === null ? x(name, children) : x(name, properties, children)
49-
}
50-
)
49+
export function jsx(name, props, _key) {
50+
const {children, ...properties} = props
51+
return name === null
52+
? x(name, children)
53+
: // @ts-expect-error: overloads are complex.
54+
x(name, properties, children)
55+
}
5156

5257
export const jsxs = jsx
5358

package.json

+12-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"xo": "^0.55.0"
6464
},
6565
"scripts": {
66-
"prepack": "npm run build && npm run format",
66+
"prepack": "npm run generate && npm run build && npm run format",
6767
"generate": "node script/generate-jsx.js",
6868
"build": "tsc --build --clean && tsc --build && tsd && type-coverage",
6969
"format": "remark . -qfo && prettier . -w --log-level warn && xo --fix",
@@ -91,6 +91,17 @@
9191
"strict": true
9292
},
9393
"xo": {
94+
"overrides": [
95+
{
96+
"files": [
97+
"**/*.ts"
98+
],
99+
"rules": {
100+
"@typescript-eslint/consistent-indexed-object-style": "off",
101+
"@typescript-eslint/consistent-type-definitions": "off"
102+
}
103+
}
104+
],
94105
"prettier": true,
95106
"rules": {
96107
"n/file-extension-in-import": "off"

readme.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ turned to strings.
242242
###### Type
243243

244244
```ts
245-
type Attributes = Record<string, string | number | boolean | null | undefined>
245+
type Attributes = Record<string, boolean | number | string | null | undefined>
246246
```
247247
248248
### `Child`
@@ -258,12 +258,13 @@ are used instead.
258258
259259
```ts
260260
type Child =
261-
| string
261+
| Array<Node | boolean | number | string | null | undefined>
262+
| Node
263+
| boolean
262264
| number
265+
| string
263266
| null
264267
| undefined
265-
| Node
266-
| Array<string | number | null | undefined | Node>
267268
```
268269
269270
### `Result`
@@ -273,7 +274,7 @@ Result from a `x` call (TypeScript type).
273274
###### Type
274275
275276
```ts
276-
type Result = Root | Element
277+
type Result = Element | Root
277278
```
278279
279280
## Syntax tree

script/generate-jsx.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import fs from 'node:fs/promises'
22
import acornJsx from 'acorn-jsx'
3+
import {buildJsx} from 'estree-util-build-jsx'
34
import {fromJs} from 'esast-util-from-js'
45
import {toJs} from 'estree-util-to-js'
5-
import {buildJsx} from 'estree-util-build-jsx'
66

77
const doc = String(
88
await fs.readFile(new URL('../test/jsx.jsx', import.meta.url))
@@ -36,16 +36,18 @@ await fs.writeFile(
3636

3737
await fs.writeFile(
3838
new URL('../test/jsx-build-jsx-automatic-development.js', import.meta.url),
39-
toJs(
40-
buildJsx(
41-
fromJs(
42-
doc.replace(
43-
/'name'/,
44-
"'jsx (estree-util-build-jsx, automatic, development)'"
39+
// There’s a problem with `this` that TS doesn’t like.
40+
'// @ts-nocheck\n\n' +
41+
toJs(
42+
buildJsx(
43+
fromJs(
44+
doc.replace(
45+
/'name'/,
46+
"'jsx (estree-util-build-jsx, automatic, development)'"
47+
),
48+
{plugins: [acornJsx()], module: true}
4549
),
46-
{plugins: [acornJsx()], module: true}
47-
),
48-
{runtime: 'automatic', importSource: 'xastscript', development: true}
49-
)
50-
).value
50+
{runtime: 'automatic', importSource: 'xastscript', development: true}
51+
)
52+
).value
5153
)

test-d/automatic.tsx

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* @jsxRuntime automatic */
22
/* @jsxImportSource xastscript */
33

4-
import {expectType, expectError} from 'tsd'
5-
import type {Root, Element} from 'xast'
4+
import {expectType} from 'tsd'
5+
import type {Element, Root} from 'xast'
66
import {x} from '../index.js'
77
import {Fragment, jsx, jsxs} from '../jsx-runtime.js'
88

@@ -41,17 +41,25 @@ expectType<Result>(
4141
<c />
4242
</a>
4343
)
44+
4445
expectType<Result>(<a>{[<b />, <c />]}</a>)
4546
expectType<Result>(<a>{[<b />, <c />]}</a>)
4647
expectType<Result>(<a>{[]}</a>)
4748

48-
expectError(<a invalid={{}} />)
49-
expectError(<a invalid={[1]} />)
50-
expectError(<a>{{invalid: 'child'}}</a>)
49+
// @ts-expect-error: not a valid child.
50+
expectType<Result>(<a invalid={{}} />)
51+
52+
// @ts-expect-error: not a valid child.
53+
expectType<Result>(<a invalid={[1]} />)
54+
55+
// @ts-expect-error: not a valid child.
56+
expectType<Result>(<a>{{invalid: 'child'}}</a>)
5157

5258
// This is where the automatic runtime differs from the classic runtime.
5359
// The automatic runtime the children prop to define JSX children, whereas it’s used as an attribute in the classic runtime.
5460
expectType<Result>(<a children={<b />} />)
5561

5662
declare function Bar(props?: Record<string, unknown>): Element
57-
expectError(<Bar />)
63+
64+
// @ts-expect-error: components not supported.
65+
expectType<Result>(<Bar />)

0 commit comments

Comments
 (0)