Skip to content

Commit

Permalink
Add generic to type data of FormResponse type #37
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-hiller committed Mar 26, 2023
1 parent b983f6f commit 4006503
Show file tree
Hide file tree
Showing 55 changed files with 343 additions and 96 deletions.
1 change: 1 addition & 0 deletions packages/qwik/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to the library will be documented in this file.
## vX.X.X (Month DD, YYYY)

- Improve types for optional properties and parameters
- Add generic to type `data` of `FormResponse` type (issue #37)

## v0.4.0 (March 25, 2023)

Expand Down
49 changes: 34 additions & 15 deletions packages/qwik/src/actions/formAction$.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,25 @@ import type {
Maybe,
MaybePromise,
PartialValues,
ResponseData,
ValidateForm,
} from '../types';
import { getFormDataValues } from '../utils';

export type FormActionResult<TFieldValues extends FieldValues> =
FormResponse & {
errors?: Maybe<FormErrors<TFieldValues>>;
};
export type FormActionResult<
TFieldValues extends FieldValues,
TResponseData extends ResponseData
> = FormResponse<TResponseData> & {
errors?: Maybe<FormErrors<TFieldValues>>;
};

type FormActionFunc<TFieldValues extends FieldValues> = (
type FormActionFunc<
TFieldValues extends FieldValues,
TResponseData extends ResponseData
> = (
values: TFieldValues,
event: RequestEventAction
) => MaybePromise<FormActionResult<TFieldValues> | void>;
) => MaybePromise<FormActionResult<TFieldValues, TResponseData> | void>;

type FormActionArg2<TFieldValues extends FieldValues> =
| QRL<ValidateForm<TFieldValues>>
Expand All @@ -36,16 +42,23 @@ type FormActionArg2<TFieldValues extends FieldValues> =
/**
* See {@link formAction$}
*/
export function formActionQrl<TFieldValues extends FieldValues>(
action: QRL<FormActionFunc<TFieldValues>>,
export function formActionQrl<
TFieldValues extends FieldValues,
TResponseData extends ResponseData = undefined
>(
action: QRL<FormActionFunc<TFieldValues, TResponseData>>,
arg2?: Maybe<FormActionArg2<TFieldValues>>
): Action<FormActionStore<TFieldValues>, PartialValues<TFieldValues>, true> {
): Action<
FormActionStore<TFieldValues, TResponseData>,
PartialValues<TFieldValues>,
true
> {
return globalActionQrl(
$(
async (
jsonData: unknown,
event: RequestEventAction
): Promise<FormActionStore<TFieldValues>> => {
): Promise<FormActionStore<TFieldValues, TResponseData>> => {
// Destructure validate function and form data info
const { validate, ...formDataInfo } =
typeof arg2 === 'object' ? arg2 : { validate: arg2 };
Expand All @@ -66,7 +79,7 @@ export function formActionQrl<TFieldValues extends FieldValues>(
const errors = validate ? await validate(values) : {};

// Create form action store object
let formActionStore: FormActionStore<TFieldValues> = {
let formActionStore: FormActionStore<TFieldValues, TResponseData> = {
values,
errors,
response: {},
Expand Down Expand Up @@ -115,8 +128,14 @@ export function formActionQrl<TFieldValues extends FieldValues>(
*
* @returns Form action constructor.
*/
export const formAction$: <TFieldValues extends FieldValues>(
actionQrl: FormActionFunc<TFieldValues>,
export const formAction$: <
TFieldValues extends FieldValues,
TResponseData extends ResponseData = undefined
>(
actionQrl: FormActionFunc<TFieldValues, TResponseData>,
arg2?: Maybe<FormActionArg2<TFieldValues>>
) => Action<FormActionStore<TFieldValues>, PartialValues<TFieldValues>, true> =
implicit$FirstArg(formActionQrl);
) => Action<
FormActionStore<TFieldValues, TResponseData>,
PartialValues<TFieldValues>,
true
> = implicit$FirstArg(formActionQrl);
12 changes: 10 additions & 2 deletions packages/qwik/src/components/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
FormStore,
Maybe,
MaybeArray,
ResponseData,
ValidateField,
} from '../types';
import {
Expand All @@ -24,10 +25,11 @@ import { Lifecycle } from './Lifecycle';

export type FieldProps<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
> = {
of: FormStore<TFieldValues, TFieldName, TFieldArrayName>;
of: FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName>;
name: TFieldName;
children: (
store: FieldStore<TFieldValues, TFieldName>,
Expand All @@ -46,13 +48,19 @@ export type FieldProps<
*/
export function Field<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>({
children,
name,
...props
}: FieldProps<TFieldValues, TFieldName, TFieldArrayName>): JSX.Element {
}: FieldProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>): JSX.Element {
// Destructure props
const { of: form } = props;

Expand Down
12 changes: 10 additions & 2 deletions packages/qwik/src/components/FieldArray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import type {
ValidateFieldArray,
MaybeArray,
Maybe,
ResponseData,
} from '../types';
import { getFieldArrayStore } from '../utils';
import { Lifecycle } from './Lifecycle';

export type FieldArrayProps<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
> = {
of: FormStore<TFieldValues, TFieldName, TFieldArrayName>;
of: FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName>;
name: TFieldArrayName;
children: (
store: FieldArrayStore<TFieldValues, TFieldArrayName>
Expand All @@ -33,13 +35,19 @@ export type FieldArrayProps<
*/
export function FieldArray<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>({
children,
name,
...props
}: FieldArrayProps<TFieldValues, TFieldName, TFieldArrayName>): JSX.Element {
}: FieldArrayProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>): JSX.Element {
// Destructure props
const { of: form } = props;

Expand Down
14 changes: 11 additions & 3 deletions packages/qwik/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ import type {
FormActionStore,
PartialValues,
Maybe,
ResponseData,
} from '../types';
import { setErrorResponse } from '../utils';

export type FormProps<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
> = {
// Custom props
of: FormStore<TFieldValues, TFieldName, TFieldArrayName>;
of: FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName>;
action?: Maybe<
ActionStore<
FormActionStore<TFieldValues>,
FormActionStore<TFieldValues, TResponseData>,
PartialValues<TFieldValues>,
true
>
Expand All @@ -50,6 +52,7 @@ export type FormProps<
*/
export function Form<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>({
Expand All @@ -64,7 +67,12 @@ export function Form<
reloadDocument,
children,
...formProps
}: FormProps<TFieldValues, TFieldName, TFieldArrayName>): JSX.Element {
}: FormProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>): JSX.Element {
// Destructure form props
const { encType } = formProps;

Expand Down
11 changes: 9 additions & 2 deletions packages/qwik/src/components/Lifecycle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
FormStore,
Maybe,
MaybeArray,
ResponseData,
ValidateField,
ValidateFieldArray,
} from '../types';
Expand All @@ -43,14 +44,15 @@ type FieldArrayProps<

type LifecycleProps<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
> = (
| FieldProps<TFieldValues, TFieldName>
| FieldArrayProps<TFieldValues, TFieldArrayName>
) & {
key: string | number;
of: FormStore<TFieldValues, TFieldName, TFieldArrayName>;
of: FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName>;
keepActive?: Maybe<boolean>;
keepState?: Maybe<boolean>;
};
Expand All @@ -61,15 +63,19 @@ type LifecycleProps<
*/
export const Lifecycle: <
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>(
props: PublicProps<LifecycleProps<TFieldValues, TFieldName, TFieldArrayName>>,
props: PublicProps<
LifecycleProps<TFieldValues, TResponseData, TFieldName, TFieldArrayName>
>,
key: string | null,
flags: number
) => JSXNode | null = component$(
<
TFieldValues extends FieldValues,
TResponseData extends ResponseData,
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>({
Expand All @@ -80,6 +86,7 @@ export const Lifecycle: <
keepState = true,
}: LifecycleProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>): JSX.Element => {
Expand Down
34 changes: 26 additions & 8 deletions packages/qwik/src/hooks/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
FieldValues,
FormOptions,
FormStore,
ResponseData,
} from '../types';
import { useFormStore } from './useFormStore';

Expand All @@ -26,31 +27,40 @@ import { useFormStore } from './useFormStore';
*/
export function useForm<
TFieldValues extends FieldValues,
TResponseData extends ResponseData = undefined,
TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues> = FieldArrayPath<TFieldValues>
>(
options: FormOptions<TFieldValues>
options: FormOptions<TFieldValues, TResponseData>
): [
FormStore<TFieldValues, TFieldName, TFieldArrayName>,
FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName>,
{
Form: (
props: Omit<
FormProps<TFieldValues, TFieldName, TFieldArrayName>,
FormProps<TFieldValues, TResponseData, TFieldName, TFieldArrayName>,
'of' | 'action'
>
) => JSX.Element;
Field: <
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>(
props: Omit<FieldProps<TFieldValues, TFieldName, TFieldArrayName>, 'of'>
props: Omit<
FieldProps<TFieldValues, TResponseData, TFieldName, TFieldArrayName>,
'of'
>
) => JSX.Element;
FieldArray: <
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>(
props: Omit<
FieldArrayProps<TFieldValues, TFieldName, TFieldArrayName>,
FieldArrayProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>,
'of'
>
) => JSX.Element;
Expand All @@ -65,22 +75,30 @@ export function useForm<
{
Form: (
props: Omit<
FormProps<TFieldValues, TFieldName, TFieldArrayName>,
FormProps<TFieldValues, TResponseData, TFieldName, TFieldArrayName>,
'of' | 'action'
>
) => Form({ of: form, action: options.action, ...props }),
Field: <
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>(
props: Omit<FieldProps<TFieldValues, TFieldName, TFieldArrayName>, 'of'>
props: Omit<
FieldProps<TFieldValues, TResponseData, TFieldName, TFieldArrayName>,
'of'
>
) => Field({ of: form, ...props }),
FieldArray: <
TFieldName extends FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues>
>(
props: Omit<
FieldArrayProps<TFieldValues, TFieldName, TFieldArrayName>,
FieldArrayProps<
TFieldValues,
TResponseData,
TFieldName,
TFieldArrayName
>,
'of'
>
) => FieldArray({ of: form, ...props }),
Expand Down
6 changes: 4 additions & 2 deletions packages/qwik/src/hooks/useFormStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
FieldValues,
FormOptions,
FormStore,
ResponseData,
} from '../types';
import { getInitialStores } from '../utils';

Expand All @@ -17,11 +18,12 @@ import { getInitialStores } from '../utils';
*/
export function useFormStore<
TFieldValues extends FieldValues,
TResponseData extends ResponseData = undefined,
TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
TFieldArrayName extends FieldArrayPath<TFieldValues> = FieldArrayPath<TFieldValues>
>(
options: FormOptions<TFieldValues>
): FormStore<TFieldValues, TFieldName, TFieldArrayName> {
options: FormOptions<TFieldValues, TResponseData>
): FormStore<TFieldValues, TResponseData, TFieldName, TFieldArrayName> {
// Destructure options
const {
loader,
Expand Down
Loading

0 comments on commit 4006503

Please sign in to comment.