Skip to content

Commit 2586f53

Browse files
committed
Rework global types
- the `.d.ts` files aren't type checked so switched to regular .ts files so we get actual type errors on them - defined public types on the global namespace in remix-types.ts because defining them afterward requires the type signatures be completely duplicated, thinking every package has a remix-types.ts (or some other conventional name) to define all public types (kinda prefer this anyway so internal/external consumers all use the same types, less to think about)
1 parent a35c891 commit 2586f53

File tree

5 files changed

+77
-56
lines changed

5 files changed

+77
-56
lines changed

packages/component/src/lib/create-element.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { jsx } from './jsx.ts'
2-
import type { RemixElement } from './remix-types.ts'
32

43
export function createElement(
54
type: string,
65
props: Record<string, any>,
76
...children: any[]
8-
): RemixElement {
7+
): Remix.Element {
98
if (props.key != null) {
109
let { key, ...rest } = props
1110
return jsx(type, { ...rest, children }, key)

packages/component/src/lib/dom.d.ts renamed to packages/component/src/lib/dom.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
* - License: MIT https://github.com/preactjs/preact/blob/eee0c6ef834534498e433f0f7a3ef679efd24380/LICENSE
55
* - Copyright (c) 2015-present Jason Miller
66
*/
7-
import type { RemixProps } from './remix-types.d.ts'
8-
97
type Booleanish = boolean | 'true' | 'false'
108

119
export type Trackable<T> = T
@@ -774,7 +772,7 @@ export type DPubAriaRole =
774772
export type AriaRole = WAIAriaRole | DPubAriaRole
775773

776774
export interface AllHTMLProps<eventTarget extends EventTarget = EventTarget>
777-
extends RemixProps<eventTarget>,
775+
extends Remix.HostProps<eventTarget>,
778776
AriaProps {
779777
// Standard HTML Attributes
780778
accept?: Trackable<string | undefined>
@@ -1018,7 +1016,7 @@ export interface AllHTMLProps<eventTarget extends EventTarget = EventTarget>
10181016
}
10191017

10201018
export interface HTMLProps<eventTarget extends EventTarget = EventTarget>
1021-
extends RemixProps<eventTarget>,
1019+
extends Remix.HostProps<eventTarget>,
10221020
AriaProps {
10231021
// Standard HTML Attributes
10241022
accesskey?: Trackable<string | undefined>

packages/component/src/lib/jsx.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
// import './remix-types.ts'
12
import type * as dom from './dom.d.ts'
2-
import type { RemixElement } from './remix-types.ts'
33

4-
export function jsx(type: string, props: Record<string, any>, key?: string): RemixElement {
4+
export function jsx(
5+
type: Remix.ElementType,
6+
props: Remix.ElementProps,
7+
key?: string,
8+
): Remix.Element {
59
return { type, props, key, $rmx: true }
610
}
711

packages/component/src/lib/remix-types.d.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import type { EventListeners } from '@remix-run/interaction'
2+
3+
declare global {
4+
namespace Remix {
5+
/**
6+
* Any valid element type accepted by JSX or `createElement`.
7+
* - `string` for host elements (e.g., 'div')
8+
* - `Function` for user components
9+
*/
10+
export type ElementType = string | Function
11+
12+
/**
13+
* Generic bag of props passed to elements/components.
14+
* Consumers should define specific prop types on their components; this is the
15+
* renderer's normalized shape used throughout reconciler/SSR code.
16+
*/
17+
export type ElementProps = Record<string, any>
18+
19+
/**
20+
* A virtual element produced by JSX/`createElement` describing UI. Carries a
21+
* `$rmx` brand used to distinguish it from plain objects at runtime.
22+
*/
23+
export interface Element {
24+
type: ElementType
25+
props: ElementProps
26+
key?: string | undefined
27+
$rmx: true
28+
}
29+
30+
/**
31+
* Any single value Remix can render. Booleans render as empty text.
32+
*/
33+
export type Renderable = Element | string | number | bigint | boolean | null | undefined
34+
35+
/**
36+
* Anything that Remix can render, including arrays of renderable values.
37+
* Particularly useful for `props.children`.
38+
*
39+
* ```tsx
40+
* function MyComponent({ children }: { children: RemixNode }) {}
41+
* ```
42+
*/
43+
export type Node = Renderable | Renderable[]
44+
45+
export interface HostProps<eventTarget extends EventTarget> {
46+
children?: Node
47+
on?: EventListeners<eventTarget> | undefined
48+
css?: 'TODO: support css properties' | undefined
49+
connect?: 'TODO: support connect' | undefined
50+
}
51+
52+
/**
53+
* Get the props for a specific element type with normalized `on` prop.
54+
*
55+
* @example
56+
* interface MyButtonProps extends Props<"button"> {
57+
* size: "sm" | "md" | "lg"
58+
* }
59+
*
60+
* @example
61+
* function Button({ on = [], ...rest }: Props<"button">) {
62+
* // on is always EventDescriptor[] here
63+
* return <button {...rest} on={[...on, dom.click(handler)]} />
64+
* }
65+
*/
66+
export type Props<T extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[T]
67+
}
68+
}

0 commit comments

Comments
 (0)