diff --git a/packages/docs/src/routes/api/qwik/api.json b/packages/docs/src/routes/api/qwik/api.json index 651d27b0534..1ac65209b0c 100644 --- a/packages/docs/src/routes/api/qwik/api.json +++ b/packages/docs/src/routes/api/qwik/api.json @@ -1624,7 +1624,7 @@ } ], "kind": "TypeAlias", - "content": "```typescript\nexport type PropFunctionProps = {\n [K in keyof PROPS]: NonNullable extends (...args: infer ARGS) => infer RET ? PropFnInterface> : PROPS[K];\n};\n```\n**References:** [PropFnInterface](#propfninterface)", + "content": "```typescript\nexport type PropFunctionProps = {\n [K in keyof PROPS]: PROPS[K] extends undefined ? PROPS[K] : PROPS[K] extends ((...args: infer ARGS) => infer RET) | undefined ? PropFnInterface> : PROPS[K];\n};\n```\n**References:** [PropFnInterface](#propfninterface)", "editUrl": "https://github.com/BuilderIO/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", "mdFile": "qwik.propfunctionprops.md" }, diff --git a/packages/docs/src/routes/api/qwik/index.md b/packages/docs/src/routes/api/qwik/index.md index 9d4b11a9d20..d1233fe2a2b 100644 --- a/packages/docs/src/routes/api/qwik/index.md +++ b/packages/docs/src/routes/api/qwik/index.md @@ -2123,9 +2123,9 @@ export type PropFunction any> = ```typescript export type PropFunctionProps = { - [K in keyof PROPS]: NonNullable extends ( - ...args: infer ARGS - ) => infer RET + [K in keyof PROPS]: PROPS[K] extends undefined + ? PROPS[K] + : PROPS[K] extends ((...args: infer ARGS) => infer RET) | undefined ? PropFnInterface> : PROPS[K]; }; diff --git a/packages/qwik/src/core/api.md b/packages/qwik/src/core/api.md index 0e0f9f40537..8883396673f 100644 --- a/packages/qwik/src/core/api.md +++ b/packages/qwik/src/core/api.md @@ -1401,7 +1401,7 @@ export type PropFunction any> = T exten // @public (undocumented) export type PropFunctionProps = { - [K in keyof PROPS]: NonNullable extends (...args: infer ARGS) => infer RET ? PropFnInterface> : PROPS[K]; + [K in keyof PROPS]: PROPS[K] extends undefined ? PROPS[K] : PROPS[K] extends ((...args: infer ARGS) => infer RET) | undefined ? PropFnInterface> : PROPS[K]; }; // @public diff --git a/packages/qwik/src/core/component/component.public.ts b/packages/qwik/src/core/component/component.public.ts index 810b51dbf9f..e2cd155b548 100644 --- a/packages/qwik/src/core/component/component.public.ts +++ b/packages/qwik/src/core/component/component.public.ts @@ -162,7 +162,9 @@ export const isQwikComponent = (component: any): component is Component => /** @public */ export type PropFunctionProps = { - [K in keyof PROPS]: NonNullable extends (...args: infer ARGS) => infer RET + [K in keyof PROPS]: PROPS[K] extends undefined + ? PROPS[K] + : PROPS[K] extends ((...args: infer ARGS) => infer RET) | undefined ? PropFnInterface> : PROPS[K]; }; diff --git a/packages/qwik/src/core/component/component.unit.tsx b/packages/qwik/src/core/component/component.unit.tsx index e5250eb61dc..d161095ec1b 100644 --- a/packages/qwik/src/core/component/component.unit.tsx +++ b/packages/qwik/src/core/component/component.unit.tsx @@ -2,10 +2,12 @@ import { createDOM } from '../../testing/library'; import { expectDOM } from '../../testing/expect-dom'; import { inlinedQrl } from '../qrl/qrl'; import { useStylesQrl } from '../use/use-styles'; -import { type PropsOf, component$ } from './component.public'; +import { type PropsOf, component$, type PropFunctionProps } from './component.public'; import { useStore } from '../use/use-store.public'; import { useLexicalScope } from '../use/use-lexical-scope.public'; import { describe, test } from 'vitest'; +import type { InputHTMLAttributes } from '../render/jsx/types/jsx-generated'; +import type { QwikIntrinsicElements } from '../render/jsx/types/jsx-qwik-elements'; describe('q-component', () => { /** @@ -113,6 +115,59 @@ describe('q-component', () => { ` ); }); + + test('types work as expected', () => { + const Input1 = component$>((props) => { + return ; + }); + + const Input2 = component$((props: PropFunctionProps>) => { + return ; + }); + + const Input3 = component$((props: Partial>) => { + return ; + }); + + const Input4 = component$( + (props: Partial>>) => { + return ; + } + ); + + type Input5Props = { + type: 'text' | 'number'; + } & Partial>; + + const Input5 = component$(({ type, ...props }) => { + return ; + }); + + type Input6Props = { + type: 'text' | 'number'; + } & QwikIntrinsicElements['input']; + + const Input6 = component$(({ type, ...props }) => { + return ( +
+ +
+ ); + }); + + component$(() => { + return ( + <> + + + + + + + + ); + }); + }); }); /////////////////////////////////////////////////////////////////////////////