-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add TypeScript Return Types for useForm #16
Comments
We will likely improve this soon. Going to close, however, as it isn't a functional bug. |
I've made a quick vue composable which covers the basics. Not at all a complete solution. import { reactive, ref, watch } from 'vue';
import type { RequestMethod, SimpleValidationErrors, ValidationConfig, ValidationErrors } from 'laravel-precognition';
import { useForm } from 'laravel-precognition-vue-inertia';
import type { VisitOptions } from '@inertiajs/core';
export function useFormPrecognition<Data extends Record<string, unknown>>(
method: RequestMethod | (() => RequestMethod),
url: string | (() => string),
inputs: Data,
config: ValidationConfig = {}
): Data & {
submit: (options?: Partial<VisitOptions>) => void;
invalid: (label: keyof Data) => boolean;
validate: (label: keyof Data) => void;
processing: boolean;
validating: boolean;
hasErrors: boolean;
forgetError: (label: keyof Data) => void;
reset: () => void;
setData: (label: keyof Data, value: unknown) => void;
errors: { [label in keyof Data]: ValidationErrors | SimpleValidationErrors };
isDirty: boolean;
isFieldDirty: (label: keyof Data) => boolean;
initialFieldValue: (label: keyof Data) => unknown;
data: () => Data;
} {
const initialState = reactive({ ...inputs });
const form = useForm(method, url, inputs, config);
const isDirtyRef = ref(false);
watch(
() => form.data(),
(newVal, _oldVal) => {
isDirtyRef.value = JSON.stringify(initialState) !== JSON.stringify(newVal);
},
{ deep: true }
);
function isFieldDirty(label: keyof Data): boolean {
const currentData = form.data() as Record<keyof Data, unknown>;
const initialData = initialState as Record<keyof Data, unknown>;
return JSON.stringify(initialData[label]) !== JSON.stringify(currentData[label]);
}
function initialFieldValue(label: keyof Data): unknown {
const initialData = initialState as Record<keyof Data, unknown>;
return initialData[label];
}
// Proxying form object to add isDirty property
const state: any = new Proxy(form, {
get(target, prop: string) {
if (prop === 'isDirty') {
return isDirtyRef.value;
}
if (prop === 'isFieldDirty') {
return isFieldDirty;
}
if (prop === 'initialFieldValue') {
return initialFieldValue;
}
return target[prop];
},
set(target, prop: string, value) {
if (prop === 'isDirty') {
isDirtyRef.value = value;
return true;
}
target[prop] = value;
return true;
}
});
return state;
} |
is there a way to import a type from laravel-precognition-vue-inertia ? i'm doing that : const form: Ref<{submit: Function, clearErrors: Function, reset: Function}|null> = ref(null); with the functions i plan to use, It's an edit form, and i need to wait for the user to actually edit something before calling useForm, edit: This seems to work : const form: Ref<ReturnType<typeof useForm>|null> = ref(null); |
See #110. |
Currently the Inertia
useForm
for React and Vue has a return type ofany
, it would be awesome to have it typed.EDIT: Actually when testing on my fork, we can probably get rid of the implicit
any
return and let typescript infer the type correctly, but it's giving me an weird error on the vue-inertia package. So probably better to type it!The text was updated successfully, but these errors were encountered: