در این مقاله قصد داریم تا با روشهایی که میتوانیم با استفاده از آنها تایپ درست مربوط به Event را تعیین کنیم، آشنا شویم.
هنگامی که با React و تایپ اسکریپت کار میکنیم، اغلب با این نوع خطا مواجه میشویم:
const onChange = (e) => {}; Parameter 'e' implicitly has an 'any' type. <input onChange={onChange} />;
همیشه مشخص نیست که باید چه تایپی را به e
در داخل تابع onChange
بدهیم.
این مشکل میتواند با onClick
، onSubmit
یا هر event handler دیگری که المنتهای DOM را دریافت می کند اتفاق بیفتد.
برای حل این مشکل چندین راه حل وجود دارد که در ادامه مقاله آنها را بررسی خواهیم کرد.
اولین راه حل این است که ماوس را روی تایپ چیزی که میخواهیم به آن منتقل کنیم، نگه داریم. به عنوان مثال اگر ماوس را روی onChange
نگه داریم خواهیم دید:
<input onChange={onChange} />; (property) React.InputHTMLAttributes<HTMLInputElement>.onChange?: React.ChangeEventHandler<HTMLInputElement> | undefined
همانطور که میبینیم یک تایپ طولانی را در خروجی نمایش میدهد:
React.InputHTMLAttributes<HTMLInputElement>.onChange?: React.ChangeEventHandler<HTMLInputElement> | undefined
بخشی که ما میخواهیم این است: React.ChangeEventHandler<HTMLInputElement>
. میتوانیم از آن برای نوشتن تابع onChange
خود استفاده نماییم:
import React from "react"; const onChange: React.ChangeEventHandler< HTMLInputElement > = (e) => { console.log(e); }; <input onChange={onChange} />;
گاهی اوقات ما نمیخواهیم کل تابع را بنویسیم، فقط قصد داریم event را داشته باشیم.
برای اینکه بتوانیم تایپ درست مناسب event را extract کنیم باید رفتار متفاوتی داشته باشیم. ابتدا یک تابع inline در داخل onChange
بسازیم.
<input onChange={(e) => {}} />
اکنون به e
دسترسی داریم، میتوانیم ماوس را روی آن قرار دهیم و تایپ صحیح event را دریافت کنیم:
<input onChange={(e) => {}} /> (parameter) e: React.ChangeEvent<HTMLInputElement>
در نهایت، میتوانیم آن تایپ را کپی کرده و از آن برای نوشتن تابع onChange
خود استفاده نماییم:
import React from "react"; const onChange = ( e: React.ChangeEvent<HTMLInputElement> ) => { console.log(e); }; <input onChange={onChange} />;
یک راه برای سرعت بخشیدن به این امر حذف مرحلهای است که در آن تایپ handler را بررسی میکنیم. خیلی خوب است که ما بتوانیم تایپ handler مورد نظرمان را تعیین کنیم و تایپ اسکریپت بقیه موارد را مشخص کند.
برای این کار میتوانیم از یک تایپ کمکی به نام ComponentProps
استفاده نماییم.
import React from "react"; const onChange: React.ComponentProps<"input">["onChange"] = (e) => { console.log(e); }; <input onChange={onChange} />;
با ارسال input
به ComponentProps
، به تایپ اسکریپت میگوییم که ما props را برای المنت input
میخواهیم.
سپس، ویژگی onChange
را از آن props میگیریم و از آن برای نوشتن تابع خود استفاده میکنیم.
این مورد بسیار خوب است، اما هنوز مجبور هستیم تابع onChange
را بنویسیم. اما اگر بخواهیم فقط تایپ event را extract کنیم چه کاری باید انجام دهیم؟
برای این کار میتوانیم از ترکیبی از Parameters
، NonNullable
و access typeهای ایندکس شده برای رسیدن به آنجا استفاده نماییم.
import React from "react"; const onChange = ( e: Parameters< NonNullable<React.ComponentProps<"input">["onChange"]> >[0] ) => {};
اما این کد بسیار زیاد است. در عوض، بیایید یک تایپ کمکی به نام EventFor
را تصور کنیم:
const onChange = (e: EventFor<"input", "onChange">) => { console.log(e); }; <input onChange={onChange} />;
این تایپ کمکی، تایپ المنت و تایپ handler را میگیرد و تایپ event را return میکند. به این ترتیب، روی هر یک از پارامترها autocomplete دریافت میکنیم و نیازی نیست تابع را بنویسیم.
اما مشکلی که وجود دارد این است که ما باید یک تایپ کمکی نسبتا بزرگ در پایگاه کد خود نگه داریم. این کد:
type GetEventHandlers< T extends keyof JSX.IntrinsicElements > = Extract<keyof JSX.IntrinsicElements[T], `on${string}`>; /** * Provides the event type for a given element and handler. * * @example * * type MyEvent = EventFor<"input", "onChange">; */ export type EventFor< TElement extends keyof JSX.IntrinsicElements, THandler extends GetEventHandlers<TElement> > = JSX.IntrinsicElements[TElement][THandler] extends | ((e: infer TEvent) => any) | undefined ? TEvent : never;
به طور کلی استفاده از راه حل EventFor
توصیه میشود. به این دلیل که:
اما اگر دلایل بالا برای ما قابل قول نبود، راه حل ComponentProps
یک جایگزین عالی برای این کار است.
۵۰ درصد تخفیف ویژه زمستان فرانت کست تا ۱۴ دی
کد تخفیف: wnt
دیدگاهها: