typescript - Sveltekit-ში, შეგიძლია დაბრუნო 2 წარუმატებელი ActionResult?


ჩემს +page.server.ts ფაილში მაქვს ფორმის მოქმედება და ვწერ დაბრუნებას fail-ს, თუ zod სქემის ვალიდაცია ვერ ჩაივლის, რაც მუშაობს. თუმცა, როდესაც ვბრუნებ სხვა fail-ს, როცა PocketBase გამოაგდებს იმეილის უკვე გამოყენების შეცდომას, ვიღებ ამ ტიპის შეცდომას ყველა ველზე, გარდა იმეილისა.

Typescript Warning
Property 'password' does not exist on type '{ password?: string[] | undefined; passwordConfirm?: string[] | undefined; email?: string[] | undefined; name?: string[] | undefined; terms?: string[] | undefined; } | { email: string[]; }'.
  Property 'password' does not exist on type '{ email: string[]; }'

კითხვები :

  1. შეიძლება ერთზე მეტი fail გააგზავნოს +page.server.ts ფაილიდან?
  2. როგორ შემიძლია სწორად გამოვასწორო ამ ტიპის გაფრთხილებები?
  3. მართად გავაკეთებ ამას, თუ არა, როგორ შემიძლია გამოვასწორო?
+page.svelte
...
    <input id="password"
           name="password"
           type="password"
           placeholder="Password"
           class="input input-bordered w-full" 
    />
    <label class="label" for="password">
        {#if form?.errors?.password}
                       <!--^^^Type Error Here-->
            <span class="label-text-alt text-error">{form?.errors?.password[0]}</span>
                                                               <!--^^^Type Error Here-->
        {/if}
    </label>
...
//Type of errors coming from +page.server.ts into +page.svelte
(property) errors: {
    password?: string[] | undefined;
    passwordConfirm?: string[] | undefined;
    email?: string[] | undefined;
    name?: string[] | undefined;
    terms?: string[] | undefined;
} | {
    email: string[];
} | undefined
+page.server.ts
export const actions: Actions = {
    default: async ({ locals, request }) => {
        const formData = Object.fromEntries(await request.formData()) as {
            email: string;
            password: string;
            passwordConfirm: string;
            name: string;
            terms: string;
        };

        const result = registerSchema.safeParse(formData);

        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const { password, passwordConfirm, ...rest } = formData;

        if (!result.success) {
            const { fieldErrors: errors } = result.error.flatten();
            const data = {
                data: rest,
                errors
            };
            return fail(400, data);
        }

        try {
            await locals.pb.collection('users').create(formData);
            await locals.pb.collection('users').authWithPassword(formData.email, formData.password);
        } catch (e) {
            if (e instanceof ClientResponseError) {
                const data = {
                    data: rest,
                    errors: {
                          email: ['Email already exists']
                    }
                };
                return fail(400, data);
            }
            throw error(500, 'Something went wrong');
        }
        throw redirect(303, '/');
    }
};

პასუხი #1

თქვენ შეგიძლიათ დაბრუნდეთ მხოლოდ ერთი წარუმატებელი შედეგი.

თუ ორი დაყვანილი შედეგი შენარჩუნდება, მაგრამ გსურთ TS-ის პრობლემის გამოსწორება, შეგიძლიათ გამოაცხადოთ ტიპი და დაადასტუროთ, რომ ელფოსტის შემოწმების შეცდომები შეესაბამება მას. მაგალითად.

const formData = Object.fromEntries(await request.formData()) as {
    email: string;
    password: string;
};

const schema = z.object({
    email: z.string().email(),
    password: z.string().min(8),
});

// This matches errors of Zob validation
type Errors = Partial<Record<keyof typeof formData, string[]>>;

const result = schema.safeParse(formData);
if (!result.success) {
    return fail(400, {
        errors: result.error.flatten().fieldErrors,
    });
}

if (formData.email == '[email ') {
    return fail(400, {
        errors: {
            email: ['already exists'],
        } as Errors, // This ensures that the errors type is the same
    });
}

return { message: 'ok' };

შენიშნეთ, რომ as Errors არ დაიჭერს ზედმეტ თვისებებს. ასე რომ, თუ თქვენ გადაასმითებთ თვისებას, კომპაილერის შეცდომას ვერ მიიღებთ.

errors-ის ტიპი მიიღება ფუნქციის მიერ შესაძლებელი ყველა დაბრუნებული მნიშვნელობიდან, ამიტომ თუ თავიდან მოერთვათ ყველა შეცდომა ერთ ობიექტში და დაბრუნდება მხოლოდ ერთი წარუმატებელი შედეგი, ტიპების შეუსაბამობა უკვე უნდა იყოს გადაწყვეტილი გაერთიანებით.

თუ Zod-ში იქნებოდა ასინქრონული ვალიდაციის მხარდაჭერა, თქვენ შეძლებდით სრულ ვალიდაციას სწორედ ასე. ამჟამად, ალბათ, მოგიწევთ ეს ხელით გააკეთოთ ან გამოიყენოთ ობიექტების გაერთიანების ბიბლიოთეკა.