2026-07-23 15:39:53 +08:00
|
|
|
import type { Dayjs } from 'dayjs';
|
|
|
|
|
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
|
|
type DateRange = [Dayjs, Dayjs];
|
|
|
|
|
|
2026-07-24 10:05:27 +08:00
|
|
|
type OptionalDateRangeField<
|
|
|
|
|
TFormValues extends Record<string, unknown>,
|
|
|
|
|
TRangeField extends keyof TFormValues,
|
|
|
|
|
> =
|
|
|
|
|
Record<never, never> extends Pick<TFormValues, TRangeField>
|
|
|
|
|
? [Exclude<TFormValues[TRangeField], undefined>] extends [never]
|
|
|
|
|
? never
|
|
|
|
|
: Exclude<TFormValues[TRangeField], undefined> extends DateRange
|
|
|
|
|
? TRangeField
|
|
|
|
|
: never
|
|
|
|
|
: never;
|
|
|
|
|
|
2026-07-23 15:39:53 +08:00
|
|
|
type DateRangeSubmitValues<
|
|
|
|
|
TFormValues extends Record<string, unknown>,
|
|
|
|
|
TRangeField extends keyof TFormValues,
|
|
|
|
|
TStartField extends string,
|
|
|
|
|
TEndField extends string,
|
|
|
|
|
> = Omit<TFormValues, TRangeField> &
|
|
|
|
|
Record<TEndField | TStartField, string | undefined>;
|
|
|
|
|
|
|
|
|
|
interface DateRangeCodecOptions<
|
|
|
|
|
TFormValues extends Record<string, unknown>,
|
|
|
|
|
TRangeField extends keyof TFormValues & string,
|
|
|
|
|
TStartField extends string,
|
|
|
|
|
TEndField extends string,
|
|
|
|
|
> {
|
|
|
|
|
endField: TEndField;
|
2026-07-24 10:05:27 +08:00
|
|
|
rangeField: OptionalDateRangeField<TFormValues, TRangeField> & TRangeField;
|
2026-07-23 15:39:53 +08:00
|
|
|
startField: TStartField;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createDateRangeCodec<
|
|
|
|
|
TFormValues extends Record<string, unknown>,
|
|
|
|
|
>() {
|
|
|
|
|
return function createCodec<
|
|
|
|
|
TRangeField extends keyof TFormValues & string,
|
|
|
|
|
TStartField extends string,
|
|
|
|
|
TEndField extends string,
|
2026-07-24 10:05:27 +08:00
|
|
|
>(
|
|
|
|
|
options: DateRangeCodecOptions<
|
|
|
|
|
TFormValues,
|
|
|
|
|
TRangeField,
|
|
|
|
|
TStartField,
|
|
|
|
|
TEndField
|
|
|
|
|
>,
|
|
|
|
|
) {
|
|
|
|
|
const { endField, startField } = options;
|
|
|
|
|
const rangeField = options.rangeField as TRangeField;
|
2026-07-23 15:39:53 +08:00
|
|
|
type SubmitValues = DateRangeSubmitValues<
|
|
|
|
|
TFormValues,
|
|
|
|
|
TRangeField,
|
|
|
|
|
TStartField,
|
|
|
|
|
TEndField
|
|
|
|
|
>;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
decode(values: Readonly<SubmitValues>): TFormValues {
|
|
|
|
|
const { [endField]: end, [startField]: start, ...formValues } = values;
|
|
|
|
|
return {
|
|
|
|
|
...formValues,
|
|
|
|
|
...(start && end ? { [rangeField]: [dayjs(start), dayjs(end)] } : {}),
|
|
|
|
|
} as TFormValues;
|
|
|
|
|
},
|
|
|
|
|
encode(values: Readonly<TFormValues>): SubmitValues {
|
|
|
|
|
const { [rangeField]: value, ...formValues } = values;
|
|
|
|
|
const range = value as DateRange | undefined;
|
|
|
|
|
return {
|
|
|
|
|
...formValues,
|
|
|
|
|
[endField]: range?.[1]?.format('YYYY-MM-DD'),
|
|
|
|
|
[startField]: range?.[0]?.format('YYYY-MM-DD'),
|
|
|
|
|
} as SubmitValues;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|