إصدار TypeScript: 2.1.1
الشفرة
type A = { a: string; }
type B = { b: string; }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// use AorB.a
}
سلوك متوقع:
يجمع الكود بدون أخطاء. على الرغم من أن a
غير موجود (بالضرورة) في جميع مكونات الاتحاد ، فإن حقيقة وجوده لدى البعض يجب أن تسمح لي بالتحقق من .a
واستخدامه إذا كان موجودًا.
السلوك الفعلي:
يشكو Typescript: "الخاصية a غير موجودة في النوع AorB ... الخاصية a غير موجودة في النوع B."
يقول الطبيب:
لتشغيل نفس الشفرة ، سنحتاج إلى استخدام تأكيد النوع:
let pet = getSmallPet();
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
}
else {
(<Bird>pet).fly();
}
http://www.typescriptlang.org/docs/handbook/advanced-types.html
ثم في عينتك:
if ((<A>AorB).a) {
// use AorB.a
}
تكمن المشكلة هنا في أنه نظرًا لأن B
لا يعلن عن خاصية a
، فقد يكون له في وقت التشغيل خاصية a
من أي نوع محتمل (لأنه يمكنك تعيين مع أي مجموعة من الخصائص إلى B
طالما أنه يحتوي على خاصية b
من سلسلة النوع). يمكنك جعله يعمل بشكل صريح للإعلان عن خاصية a: undefined
في B
(وبالتالي ضمان أن B
لن يحتوي على خاصية a
عشوائية):
type A = { a: string; }
type B = { b: string; a: undefined }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// Ok
}
يجعل الشعور بالكمال. ضرطة الدماغ.
إذا قمت بتحديد a: undefined
على النوع B ، فسيتعين عليك تعيينه على undefined
عند إنشاء / تمرير متغير.
للتغلب على ذلك ، يمكنك إعلان a
كـ a?: undefined
، وستكون الكتابة المطبوعة سعيدة إذا حذفتها.
إذا فهمت التعليقات بشكل صحيح ، فيجب أن يعمل هذا (لكن رميات ؛ تم اختباره في الملعب): هل هذا خطأ أم لا؟ 🤔
type LinkProps = {
to: string;
onClick?: undefined;
// Link specific props:
target: string;
}
type ButtonProps = {
to?: undefined;
onClick: Function;
// Button specific props:
disabled: boolean;
}
type ActionProps = LinkProps | ButtonProps;
const Action = (props: ActionProps) =>
props.to ?
'Link with target: ' + props.target // Error not on ButtonProps
:
'Button with disabled: ' + props.disabled; // Error: not on LinkProps
Action({
to: 'dssd',
target: '_blank'
});
أنا لا أفهم هذا على الإطلاق. أليس if ((<A>AorB).a)
هو نفسه استخدام (A.a)
لأنك تجبره على إعادة كتابة A
؟
إذا قمت بتحديد
a: undefined
على النوع B ، فسيتعين عليك تعيينه علىundefined
عند إنشاء / تمرير متغير.
للتغلب على ذلك ، يمكنك إعلانa
كـa?: undefined
، وستكون الكتابة المطبوعة سعيدة إذا حذفتها.
قد يكون أفضل a?: never
، الآن لا يمكنك تعيين undefined
عن طريق الخطأ
ماذا لو لم تعطِ اسمًا لكل عضو من أعضاء الاتحاد؟ (لا يمكن إجراء تأكيد نوع على النحو الوارد أعلاه بدون اسم للنوع المؤكد ، هل يمكنني ذلك؟)
type u = "str" | {prop:"val"};
function f(arg:u){return arg.prop} // TypeScript: Property 'prop' does not exist on type 'u'
اي حل؟
أجد حلاً في الكتاب:
interface A { x: number;}
interface B { y: string;}
function doStuff ( q: A | B ) {
if ( 'x' in q) {
// if type A...
}
else {
// if type B...
}
}
مقتطف من: بصرات علي سيد. "الغوص العميق في TypeScript." كتب آبل.
خاصية على كائن ويمكن استخدامها كحارس نوع ، ويمكن لـ TypeScript معرفة النوع الذي استخدمته.
type ColorItemType = {
colorId: number,
colorName: string,
}
type NumItemType = {
numId: number,
numName: string
}
type ResType = {
itemId: number,
// 0 color 1 num
type: number,
itemInfo: {
colorList: Array<ColorItemType>
numList: Array<NumItemType>
}
}
const request = () => {
return [{
itemId: 1,
type: 0,
itemInfo: {
colorList: [{
colorId: 1,
colorName: 'blue'
}],
numList: []
}
}];
};
const dataSource: Array<ResType> = request();
const formatData = dataSource.map(dataItem => {
const list: Array<ColorItemType | NumItemType> = dataItem.type === 1 ? dataItem.itemInfo.numList : dataItem.itemInfo.colorList;
return list.map(listItem => {
return {
// An error will be reported here
value: listItem.numId || listItem.colorId,
label: listItem.numName || listItem.colorName
};
});
});
تكمن المشكلة هنا في أنه نظرًا لأن
B
لا يعلن عن خاصيةa
، فقد يكون له في وقت التشغيل خاصيةa
من أي نوع محتمل (لأنه يمكنك تعيين مع أي مجموعة من الخصائص إلىB
طالما أنه يحتوي على خاصيةb
من سلسلة النوع). يمكنك جعله يعمل بشكل صريح للإعلان عن خاصيةa: undefined
فيB
(وبالتالي ضمان أنB
لن يحتوي على خاصيةa
عشوائية):type A = { a: string; } type B = { b: string; a: undefined } type AorB = A | B; declare const AorB: AorB; if (AorB.a) { // Ok }
لا يعمل معي 07.10.2020
وأعتقد أن سلوك TS هذا ليس جيدًا لأنه لا يساعد المطور كثيرًا ...
التعليق الأكثر فائدة
أجد حلاً في الكتاب:
مقتطف من: بصرات علي سيد. "الغوص العميق في TypeScript." كتب آبل.
خاصية على كائن ويمكن استخدامها كحارس نوع ، ويمكن لـ TypeScript معرفة النوع الذي استخدمته.