Skip to content

Commit 8f31c38

Browse files
wooormremcohaszing
andauthored
Add automatic, classic runtime types
Closes GH-9 Reviewed-by: Christian Murphy <[email protected]> Co-authored-by: Remco Haszing <[email protected]>
1 parent a90a4e3 commit 8f31c38

17 files changed

+315
-14
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
.DS_Store
2-
*.d.ts
32
*.log
43
coverage/
54
node_modules/
65
test/jsx-*.js
76
yarn.lock
7+
/*.d.ts
8+
test/*.d.ts
9+
script/*.d.ts
10+
lib/*.d.ts
11+
!lib/jsx-automatic.d.ts
12+
!lib/jsx-classic.d.ts

index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1+
/**
2+
* @typedef {import('./lib/index.js').XChild}} Child Acceptable child value
3+
* @typedef {import('./lib/index.js').XAttributes}} Attributes Acceptable attributes value.
4+
*/
5+
16
export {x} from './lib/index.js'

jsx-runtime.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* @typedef {import('./lib/runtime.js').JSXProps}} JSXProps
3+
*/
4+
5+
export * from './lib/runtime.js'

lib/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
* @typedef {string|number|null|undefined} XPrimitiveChild
1111
* @typedef {Array.<Node|XPrimitiveChild>} XArrayChild
1212
* @typedef {Node|XPrimitiveChild|XArrayChild} XChild
13+
* @typedef {import('./jsx-classic').Element} x.JSX.Element
14+
* @typedef {import('./jsx-classic').IntrinsicAttributes} x.JSX.IntrinsicAttributes
15+
* @typedef {import('./jsx-classic').IntrinsicElements} x.JSX.IntrinsicElements
16+
* @typedef {import('./jsx-classic').ElementChildrenAttribute} x.JSX.ElementChildrenAttribute
1317
*/
1418

1519
/**

lib/jsx-automatic.d.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {XAttributes, XChild, XResult} from './index.js'
2+
3+
export namespace JSX {
4+
/**
5+
* This defines the return value of JSX syntax.
6+
*/
7+
type Element = XResult
8+
9+
/**
10+
* This disallows the use of functional components.
11+
*/
12+
type IntrinsicAttributes = never
13+
14+
/**
15+
* This defines the prop types for known elements.
16+
*
17+
* For `xastscript` this defines any string may be used in combination with `xast` `Attributes`.
18+
*
19+
* This **must** be an interface.
20+
*/
21+
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
22+
interface IntrinsicElements {
23+
[name: string]:
24+
| XAttributes
25+
| {
26+
/**
27+
* The prop that matches `ElementChildrenAttribute` key defines the type of JSX children, defines the children type.
28+
*/
29+
children?: XChild
30+
}
31+
}
32+
33+
/**
34+
* The key of this interface defines as what prop children are passed.
35+
*/
36+
interface ElementChildrenAttribute {
37+
/**
38+
* Only the key matters, not the value.
39+
*/
40+
children?: never
41+
}
42+
}

lib/jsx-automatic.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Empty (only used for TypeScript).
2+
export {}

lib/jsx-classic.d.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {XAttributes, XChild, XResult} from './index.js'
2+
3+
/**
4+
* This unique symbol is declared to specify the key on which JSX children are passed, without conflicting
5+
* with the Attributes type.
6+
*/
7+
declare const children: unique symbol
8+
9+
/**
10+
* This defines the return value of JSX syntax.
11+
*/
12+
export type Element = XResult
13+
14+
/**
15+
* This disallows the use of functional components.
16+
*/
17+
export type IntrinsicAttributes = never
18+
19+
/**
20+
* This defines the prop types for known elements.
21+
*
22+
* For `xastscript` this defines any string may be used in combination with `xast` `Attributes`.
23+
*
24+
* This **must** be an interface.
25+
*/
26+
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
27+
export interface IntrinsicElements {
28+
[name: string]:
29+
| XAttributes
30+
| {
31+
/**
32+
* The prop that matches `ElementChildrenAttribute` key defines the type of JSX children, defines the children type.
33+
*/
34+
[children]?: XChild
35+
}
36+
}
37+
38+
/**
39+
* The key of this interface defines as what prop children are passed.
40+
*/
41+
export interface ElementChildrenAttribute {
42+
/**
43+
* Only the key matters, not the value.
44+
*/
45+
[children]?: never
46+
}

lib/jsx-classic.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Empty (only used for TypeScript).
2+
export {}

lib/runtime.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @typedef {import('./index.js').Element} Element
3+
* @typedef {import('./index.js').Root} Root
4+
* @typedef {import('./index.js').XResult} XResult
5+
* @typedef {import('./index.js').XChild} XChild
6+
* @typedef {import('./index.js').XAttributes} XAttributes
7+
* @typedef {import('./index.js').XValue} XValue
8+
*
9+
* @typedef {{[x: string]: XValue|XChild}} JSXProps
10+
*/
11+
12+
import {x} from './index.js'
13+
14+
// Export `JSX` as a global for TypeScript.
15+
export * from './jsx-automatic.js'
16+
17+
/**
18+
* Create XML trees in xast through JSX.
19+
*
20+
* @param name Qualified name. Case sensitive and can contain a namespace prefix (such as `rdf:RDF`). Pass `null|undefined` to build a root.
21+
* @param props Map of attributes. Nullish (null or undefined) or NaN values are ignored, other values (strings, booleans) are cast to strings. `children` can contain one child or a list of children. When strings are encountered, they are mapped to text nodes.
22+
*/
23+
export const jsx =
24+
/**
25+
* @type {{
26+
* (name: null|undefined, props: {children?: XChild}, key?: string): Root
27+
* (name: string, props: JSXProps, key?: string): Element
28+
* }}
29+
*/
30+
(
31+
/**
32+
* @param {string|null} name
33+
* @param {XAttributes & {children?: XChild}} props
34+
* @returns {XResult}
35+
*/
36+
function (name, props) {
37+
var {children, ...properties} = props
38+
return name === null ? x(name, children) : x(name, properties, children)
39+
}
40+
)
41+
42+
export const jsxs = jsx
43+
44+
/** @type {null} */
45+
export const Fragment = null

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,18 @@
3434
"index.d.ts",
3535
"index.js"
3636
],
37+
"exports": {
38+
".": "./index.js",
39+
"./index.js": "./index.js",
40+
"./jsx-runtime": "./jsx-runtime.js"
41+
},
3742
"dependencies": {
3843
"@types/xast": "^1.0.0"
3944
},
4045
"devDependencies": {
4146
"@babel/core": "^7.0.0",
4247
"@babel/plugin-syntax-jsx": "^7.0.0",
4348
"@babel/plugin-transform-react-jsx": "^7.0.0",
44-
"@types/acorn": "^4.0.0",
4549
"@types/babel__core": "^7.0.0",
4650
"@types/tape": "^4.0.0",
4751
"astring": "^1.0.0",
@@ -61,7 +65,7 @@
6165
},
6266
"scripts": {
6367
"prepack": "npm run build && npm run format",
64-
"build": "rimraf \"{script/**,test/**,lib/**,}*.d.ts\" && tsc && tsd && type-coverage",
68+
"build": "rimraf \"{script/**,test/**,}*.d.ts\" \"lib/{index,runtime}.d.ts\" && tsc && tsd && type-coverage",
6569
"generate": "node script/generate-jsx",
6670
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
6771
"test-api": "node test/index.js",
@@ -81,10 +85,7 @@
8185
"rules": {
8286
"no-var": "off",
8387
"prefer-arrow-callback": "off"
84-
},
85-
"ignore": [
86-
"types/"
87-
]
88+
}
8889
},
8990
"remarkConfig": {
9091
"plugins": [

0 commit comments

Comments
 (0)