أنواع شرطية توزيعية في تايبسكريبت
لذلك كنت أتصفح الوثائق الخاصة بـ TypeScript ولم أتمكن من فهم هذا المفهوم.
لذلك تنص الوثائق على :-
في حالات التهيئة من نوع الشرط التوزيعي T extends U ? X : Y، يتم حل المراجع إلى T داخل نوع الشرط إلى المكونات الفردية من نوع الاتحاد (أي أن T تشير إلى المكونات الفردية بعد توزيع نوع الشرط على نوع الاتحاد). علاوة على ذلك، فإن المراجع إلى T داخل X لها قيد إضافي على معامل النوع U (أي أن T تعتبر قابلة للإسناد إلى U داخل X).
لا أستطيع فهم الجزء T تشير إلى المكونات الفردية بعد توزيع النوع الشرطي على نوع الاتحاد.
هل يمكن لأحد أن يشرح لي هذا من فضلك. سيكون من الممتاز تقدير مثال عن نفس الشيء، فالمثال الموجود في الوثائق غير واضح بالنسبة لي.
الإجابة رقم 1
همم، لقد قرأت الوثائق للتو وأصبح الأمر منطقيًا بالنسبة لي... لا أعرف إذا كان بإمكاني شرحه بشكل أفضل من ذلك، لكن دعونا نستعرضه. فيما يلي، و...x...، تعني "بعض التعبير الذي قد يظهر فيه x".
الأنواع الشرطية التي يكون النوع المفحوص فيها عبارة عن معلمة نوع عارية تُسمى أنواع شرطية موزعة.
في هذه الحالة، يعني معامل النوع معامل نوع عام، ومعامل النوع العاري هو عبارة عن تعبير نوع يظهر فيه معامل النوع بمفرده وليس جزءًا من تعبير نوع أكثر تعقيدًا. والنوع المفحوص هو النوع الذي يظهر قبل extends. لنرَ بعض الأمثلة:
type A<T>=string extends T ? "yes" : "no"هذا ليس نوعًا شرطيًا توزيعيًا. النوع المفحوص هوstring، والذي ليس معلمة نوع عامة.type B<T>={x: T} extends {x: number} ? "نعم" : "لا"هذا ليس نوع شرطية موزعة. النوع الذي يتم التحقق منه هو{x: T}، والذي يحتوي على معامل النوعTفيه، لكنه ليس معامل نوع عاري.type C<T>=T extends string ? "yes" : "no"هذا نوع شرطي توزيعي؛ النوع الذي يتم التحقق منه هوT، وهو معامل نوع عام عارٍ.
يتم توزيع أنواع الشرطيات التوزيعية تلقائيًا على أنواع الاتحاد أثناء التحقق من النوع. على سبيل المثال، يتم حل تحقق من النوع
T extends U ? X : Yمع الوسيط النوعيA | B | CلـTكـ(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).
هذه هي جوهر ما يفعله الخاصية التوزيعية. إذا كان لديك اسم نوع F<T> معرف ليكون نوعًا شرطيًا توزيعيًا، كما في:
type F<T> = T extends ...T... ? ...T... : ...T...
بعد ذلك، F<T> سيوزع على الاتحادات، مما يعني أنه لأي نوعين A وB، سيكون النوع F<A | B> مكافئًا للنمط F<A> | F<B>
في حالات التهيئة لنوع الشرط التوزيعي
T extends U ? X : Y، يتم حل الإشارات إلىTضمن نوع الشرط إلى المكونات الفردية لنوع الاتحاد (أي أنTتشير إلى المكونات الفردية بعد توزيع نوع الشرط على نوع الاتحاد).
هذا هو الجزء الذي أربكك، لكنه مجرد شرح لكيفية عمل التوزيع. يقول إن لتقييم F<A | B>، يجب عليك تقييم F<A> | F<B>. إذن بالنسبة لـ F<A>، تأخذ F<T>=T extends ...T... ? ...T... : ...T... وتضع A مكان T (لتصبح A extends ...A... ? ...A... : ...A...)، ثم تضع B مكان T (لتصبح B extends ...B... ? ...B... : ...B...)، ثم توحدهما.
لنمر من خلال مثال ملموس:
type D<T> = T extends string ? T : "nope"
ما هذا:
type E = D<"a" | "b" | 0 | true>
حسناً، إليك كيفية عدم القيام بذلك:
type E = ("a" | "b" | 0 | true) extends string ? ("a" | "b" | 0 | true) : "nope" //👎
type E = "nope" //👎
لقد قمت للتو بإدخال "a" | "b" | 0 | true في T دون التوزيع، وهذا خطأ. إليك كيفية القيام بذلك بشكل صحيح:
type E = D<"a"> | D<"b"> | D<0> | D<true> //👍
type E = ("a" extends string ? "a" : "nope") |
("b" extends string ? "b" : "nope") |
(0 extends string ? 0 : "nope") |
(true extends string ? true : "nope") //👍
type E = ("a") | ("b") | ("nope") | ("nope") //👍
type E = "a" | "b" | "nope" //👍
انظر، لقد أخذنا "المكونات الفردية للاتحاد" واستبدلنا T بكل واحد منهم بالتتابع.
حسنًا، آمل أن يكون ذلك أوضح الآن. حظًا موفقًا!
الإجابة رقم 2
داخل نوع شرطي توزيعي (دعنا نقول type BoxIfObject<T>=T extends object ? Array<T> : T;) عندما يتم تطبيق النوع على اتحاد (دعنا نقول number | { a : string }), يكون الأمر كما لو أن النوع الشرطي يُطبق على كل مكون من مكونات الاتحاد وبالتالي داخل النوع الشرطي T سيشير بدوره إلى كل مكون من مكونات الاتحاد (لذلك T سيكون أولاً number ثم T سيكون { a : string })
لذلك عندما نطبق BoxIfObject<number | { a : string }>، T لن تشير أبدًا إلى الاتحاد الكامل number | { a : string } بل إلى كل من مكوناته على حدة. أساسًا BoxIfObject<number | { a : string }>=BoxIfObject<number> | BoxIfObject<{ a : string }>=number | Array<{ a : string }
