Skip to content

Commit

Permalink
fix: improve jsx types (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Jan 29, 2022
1 parent 8b7916d commit 0512461
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 51 deletions.
2 changes: 1 addition & 1 deletion integration/architecture/architecture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const Browser = component(
<input value="http://localhost/" />
</div>
<div class="browser-body">
<Slot />
<Slot sdfdf="df" />
</div>
</div>
));
Expand Down
44 changes: 24 additions & 20 deletions src/core/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ export function $<T>(value: T): QRL<T>;
// Warning: (ae-forgotten-export) The symbol "AsyncProps" needs to be exported by the entry point index.d.ts
//
// @public
export function Async<T>(props: AsyncProps<T>): JSXNode<AsyncProps<T>>;
export function Async<T>(props: AsyncProps<T>): JSXNode<any>;

// @public (undocumented)
export function bubble<PAYLOAD>(eventType: string, payload?: PAYLOAD): void;

// Warning: (ae-forgotten-export) The symbol "OnMountFn" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "QwikEvents" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function component$<PROPS>(onMount: OnMountFn<PROPS>): (props: PROPS) => JSXNode<PROPS>;
export function component$<PROPS extends {}>(onMount: OnMountFn<PROPS>): (props: PROPS & QwikEvents) => JSXNode<unknown>;

// @public (undocumented)
export function component<PROPS extends {}>(tagName: string, onMount: QRL<OnMountFn<PROPS>>): (props: PROPS) => JSXNode<PROPS>;
export function component<PROPS extends {}>(tagName: string, onMount: QRL<OnMountFn<PROPS>>): (props: PROPS & QwikEvents) => JSXNode<unknown>;

// @public (undocumented)
export function component<PROPS extends {}>(onMount: QRL<OnMountFn<PROPS>>): (props: PROPS) => JSXNode<PROPS>;
export function component<PROPS extends {}>(onMount: QRL<OnMountFn<PROPS>>): (props: PROPS & QwikEvents) => JSXNode<unknown>;

// @public (undocumented)
export type ComponentChild = JSXNode<any> | object | string | number | bigint | boolean | null | undefined;
Expand All @@ -48,7 +49,7 @@ export const Fragment: any;
// @public (undocumented)
export interface FunctionComponent<P = {}> {
// (undocumented)
(props: P): JSXNode<any> | null;
(props: P): JSXNode | null;
}

// @public (undocumented)
Expand Down Expand Up @@ -102,24 +103,24 @@ export const Host: FunctionComponent<Record<string, any>>;
export function implicit$FirstArg<FIRST, REST extends any[], RET>(fn: (first: QRL<FIRST>, ...rest: REST) => RET): (first: FIRST, ...rest: REST) => RET;

// @public (undocumented)
function jsx<PROPS>(type: string | FunctionComponent<PROPS>, props: PROPS, key?: string): JSXNode<PROPS>;
function jsx<T extends string | FunctionComponent<PROPS>, PROPS>(type: T, props: PROPS, key?: string): JSXNode<T>;
export { jsx }
export { jsx as jsxDEV }
export { jsx as jsxs }

// @public (undocumented)
export type JSXFactory<PROPS extends {} = any> = (props: PROPS, state?: any) => JSXNode<PROPS>;
export type JSXFactory<T, PROPS extends {} = any> = (props: PROPS, state?: any) => JSXNode<T>;

// @public (undocumented)
export interface JSXNode<PROPS = any> {
export interface JSXNode<T = any> {
// (undocumented)
children: ComponentChild[];
// (undocumented)
key: string | number | any;
// (undocumented)
props: PROPS;
props: any;
// (undocumented)
type: any;
type: T;
}

// @public
Expand Down Expand Up @@ -150,10 +151,10 @@ export const onHydrate$: (first: () => void) => void;
export function onHydrate(hydrateFn: QRL<() => void>): void;

// @public (undocumented)
export const onRender$: (first: () => JSXNode) => QRL<() => JSXNode>;
export const onRender$: <T>(first: () => JSXNode<T>) => QRL<() => JSXNode<T>>;

// @public (undocumented)
export function onRender(renderFn: QRL<() => JSXNode>): QRL<() => JSXNode>;
export function onRender<T>(renderFn: QRL<() => JSXNode<T>>): QRL<() => JSXNode<T>>;

// @public (undocumented)
export const onResume$: (first: () => void) => void;
Expand Down Expand Up @@ -247,17 +248,17 @@ export interface QwikIntrinsicElements extends IntrinsicElements {
// @public (undocumented)
export namespace QwikJSX {
// (undocumented)
export interface Element extends JSXNode<any> {
export interface Element extends JSXNode {
}
// (undocumented)
export interface ElementChildrenAttribute {
// (undocumented)
children: any;
}
// Warning: (ae-forgotten-export) The symbol "QwikIntrinsicAttributes" needs to be exported by the entry point index.d.ts
//
// (undocumented)
export interface IntrinsicAttributes {
// (undocumented)
[key: string]: any;
export interface IntrinsicAttributes extends QwikIntrinsicAttributes {
}
// (undocumented)
export interface IntrinsicElements extends QwikIntrinsicElements {
Expand All @@ -275,12 +276,11 @@ export type RenderableProps<P, RefType = any> = P & Readonly<{
// @public (undocumented)
export const setPlatform: (doc: Document, plt: CorePlatform) => CorePlatform;

// Warning: (ae-forgotten-export) The symbol "HTMLAttributes" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export const Slot: FunctionComponent<HTMLAttributes<{
export const Slot: FunctionComponent<{
name?: string;
}>>;
children?: JSXChildren;
}>;

// @public (undocumented)
export function useEvent(): Event;
Expand Down Expand Up @@ -321,6 +321,10 @@ export const withStyles$: (first: string) => void;
// @public (undocumented)
export function withStyles(styles: QRL<string>): void;

// Warnings were encountered during analysis:
//
// dist-dev/tsc-out/src/core/render/jsx/slot.public.d.ts:8:5 - (ae-forgotten-export) The symbol "JSXChildren" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

```
15 changes: 8 additions & 7 deletions src/core/component/component.public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { newInvokeContext, useInvoke, useWaitOn } from '../use/use-core';
import { useHostElement } from '../use/use-host-element.public';
import { AttributeMarker } from '../util/markers';
import { styleKey } from './qrl-styles';
import type { QwikEvents } from '../render/jsx/types/jsx-qwik-attributes';

/**
* @public
Expand Down Expand Up @@ -73,7 +74,7 @@ export const onDehydrate$ = implicit$FirstArg(onDehydrate);
/**
* @public
*/
export function onRender(renderFn: QRL<() => JSXNode>): QRL<() => JSXNode> {
export function onRender<T>(renderFn: QRL<() => JSXNode<T>>): QRL<() => JSXNode<T>> {
return toQrlOrError(renderFn);
}

Expand Down Expand Up @@ -146,27 +147,27 @@ export type PropsOf<COMP extends (props: any) => JSXNode> = COMP extends (
export function component<PROPS extends {}>(
tagName: string,
onMount: QRL<OnMountFn<PROPS>>
): (props: PROPS) => JSXNode<PROPS>;
): (props: PROPS & QwikEvents) => JSXNode<unknown>;
/**
* @public
*/
export function component<PROPS extends {}>(
onMount: QRL<OnMountFn<PROPS>>
): (props: PROPS) => JSXNode<PROPS>;
): (props: PROPS & QwikEvents) => JSXNode<unknown>;
/**
* @public
*/
export function component<PROPS extends {}>(
tagNameOrONMount: string | QRL<OnMountFn<PROPS>>,
onMount?: QRL<OnMountFn<PROPS>>
): (props: PROPS) => JSXNode<PROPS> {
) {
// Sort of the argument position based on type / overload
const hasTagName = typeof tagNameOrONMount == 'string';
const tagName = hasTagName ? tagNameOrONMount : 'div';
const onMount_ = hasTagName ? onMount! : tagNameOrONMount;

// Return a QComponent Factory function.
return function QComponent(props: PROPS): JSXNode<PROPS> {
return function QComponent(props: PROPS): JSXNode<unknown> {
const onRenderFactory: qrlFactory = async (
hostElement: Element
): Promise<ReturnType<typeof onRender>> => {
Expand All @@ -177,15 +178,15 @@ export function component<PROPS extends {}>(
const invokeCtx = newInvokeContext(hostElement);
return useInvoke(invokeCtx, onMount, componentProps);
};
return h(tagName, { 'on:qRender': onRenderFactory, ...props }) as any;
return h(tagName, { 'on:qRender': onRenderFactory, ...props });
};
}

/**
*
* @public
*/
export function component$<PROPS>(onMount: OnMountFn<PROPS>): (props: PROPS) => JSXNode<PROPS> {
export function component$<PROPS extends {}>(onMount: OnMountFn<PROPS>) {
return component($(onMount));
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/render/jsx/async.public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ export type AsyncProps<T> = AsyncResolve<T> | AsyncWithChildren<T>;
* @public
*/

export function Async<T>(props: AsyncProps<T>): JSXNode<AsyncProps<T>> {
export function Async<T>(props: AsyncProps<T>): JSXNode<any> {
// TODO(misko): implement onPending/onResolved/onError
if (!('children' in props)) {
throw new Error('IMPLEMENT');
Expand Down
1 change: 0 additions & 1 deletion src/core/render/jsx/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export declare namespace h {
export interface Element extends QwikJSX.Element {}
export interface IntrinsicAttributes extends QwikJSX.IntrinsicAttributes {}
export interface IntrinsicElements extends QwikJSX.IntrinsicElements {}
// TODO(misko): Commenting this out does not seem to make a difference.
export interface ElementChildrenAttribute {
children?: any;
}
Expand Down
6 changes: 3 additions & 3 deletions src/core/render/jsx/jsx-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { qDev } from '../../util/qdev';
/**
* @public
*/
export function jsx<PROPS>(
type: string | FunctionComponent<PROPS>,
export function jsx<T extends string | FunctionComponent<PROPS>, PROPS>(
type: T,
props: PROPS,
key?: string
): JSXNode<PROPS> {
): JSXNode<T> {
return new JSXNodeImpl(type, props, key);
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/render/jsx/slot.public.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { HTMLAttributes } from './types/jsx-generated';
import type { FunctionComponent } from './types/jsx-node';
import type { JSXChildren } from './types/jsx-qwik-attributes';

/**
* @public
*/
export const Slot: FunctionComponent<HTMLAttributes<{ name?: string }>> = {
export const Slot: FunctionComponent<{
name?: string;
children?: JSXChildren;
}> = {
__brand__: 'slot',
} as any;
1 change: 0 additions & 1 deletion src/core/render/jsx/types/jsx-generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ export type AriaRole =
| 'treeitem'
| (string & {});
export interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
children?: any;
accessKey?: string | undefined;
className?: string | undefined;
contentEditable?: Booleanish | 'inherit' | undefined;
Expand Down
10 changes: 5 additions & 5 deletions src/core/render/jsx/types/jsx-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ export type RenderableProps<
* @public
*/
export interface FunctionComponent<P = {}> {
(props: P): JSXNode<any> | null;
(props: P): JSXNode | null;
}

/**
* @public
*/
export interface JSXNode<PROPS = any> {
type: any;
props: PROPS;
export interface JSXNode<T = any> {
type: T;
props: any;
children: ComponentChild[];
key: string | number | any;
}

/**
* @public
*/
export type JSXFactory<PROPS extends {} = any> = (props: PROPS, state?: any) => JSXNode<PROPS>;
export type JSXFactory<T, PROPS extends {} = any> = (props: PROPS, state?: any) => JSXNode<T>;
23 changes: 18 additions & 5 deletions src/core/render/jsx/types/jsx-qwik-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { QRL } from '../../../import/qrl.public';
import type { JSXNode } from './jsx-node';

interface QwikProps {
export interface QwikProps {
class?: string | { [className: string]: boolean };
innerHTML?: string;

Expand All @@ -18,10 +18,10 @@ interface QwikProps {
'q:base'?: string;
}

type Event<T extends Function = Function> = T;
type Event = () => any;
type QrlEvent<T extends Event = Event> = QRL<Event>;

interface QwikEvents {
export interface QwikEvents {
// Host events
[key: `on$:${string}`]: Event;
[key: `on:${string}`]: QrlEvent;
Expand All @@ -35,8 +35,21 @@ interface QwikEvents {
[key: `onWindow:${string}`]: QrlEvent;
}

export type JSXChild = string | number | boolean | null | JSXNode<any>;
export interface QwikAttributes extends QwikProps, QwikEvents {}

export type JSXPrimitive =
| string
| number
| boolean
| null
| undefined
| Function
| RegExp
| JSXNode<any>;
export type JSXChild = JSXPrimitive | JSXPrimitive[] | Promise<JSXPrimitive>;
export type JSXChildren = JSXChild | JSXChild[];

export interface DOMAttributes<T> extends QwikProps, QwikEvents {
children?: JSXChild | JSXChild[];
children?: JSXChildren;
key?: string;
}
5 changes: 5 additions & 0 deletions src/core/render/jsx/types/jsx-qwik-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ interface QwikCustomHTMLAttributes<T> extends HTMLAttributes<T> {

interface QwikCustomHTMLElement extends HTMLElement {}

/**
* @public
*/
export interface QwikIntrinsicAttributes {}

/**
* @public
*/
Expand Down
8 changes: 3 additions & 5 deletions src/core/render/jsx/types/jsx-qwik.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import type { DOMAttributes } from './jsx-qwik-attributes';
import type { JSXNode } from './jsx-node';
import type { QwikIntrinsicElements } from './jsx-qwik-elements';
import type { QwikIntrinsicAttributes, QwikIntrinsicElements } from './jsx-qwik-elements';

/**
* @public
*/
export namespace QwikJSX {
export interface Element extends JSXNode<any> {}
export interface IntrinsicAttributes {
[key: string]: any;
}
export interface Element extends JSXNode {}
export interface IntrinsicAttributes extends QwikIntrinsicAttributes {}
export interface ElementChildrenAttribute {
children: any;
}
Expand Down

0 comments on commit 0512461

Please sign in to comment.