تايبسكريبت: لماذا يمكن أن يكون PromiseLike نوعًا ممكنًا لـ this في كائن داخل دالة غير متزامنة؟
لقد كتبت هذه الدالة لكنها تسبب خطأ ولا أفهم السبب...
const createObject = async (): Promise<MyType> => {
await Promise.resolve();
return {
async foo() {
await this.bar();
// do something else
},
async bar() {
await Promise.resolve();
// do something here
}
};
};
interface MyType {
foo: () => Promise<void>;
bar: () => Promise<void>;
}
لماذا تظهر خطأ عند استدعاء الدالة في السطر 5 من this.bar()؟ يقول لي أن this إما من النوع MyType أو PromiseLike<MyType>. النوع الثاني الممكن هو المشكلة لكنني لا أرى في أي حالة يمكن أن يكون هذا PromiseLike؟ ألم يمكنه أن يفترض أنه إذا تم استدعاء تلك الدالة، فإن هذا دائمًا كائن محمل؟
ما هي الطريقة الأكثر أناقة لتجنب هذا؟ حالياً أقوم بهذا (وهو قبيح تماماً وغير مفهوم كقارئ للكود):
await (await this).bar();
لقد اكتشفت أيضًا أن تغيير نوع الإرجاع للدالة createObject من Promise<MyType> إلى Promise<any> يحل المشكلة، لكن هذا ليس دقيقًا جدًا.
الإجابة رقم 1
نظرًا لأن createObject هي دالة غير متزامنة تُرجع Promise<MyType>، فإن عبارة الإرجاع داخلها يمكن أن تُرجع إما Promise<MyType> أو MyType. أي منهما صحيح. لذلك، عندما تقوم بإرجاع كائن حرفي مباشرة، فإن TypeScript بشكل غير بديهي إلى حد ما ستستنتج أن نوع الكائن هو Promise<MyType> | MyType، وستحدد نوع this وفقًا لذلك.
لا توجد طريقة لتغيير هذا إذا كان الكائن الحرفي موجودًا مباشرة في الرجوع. ما يمكنك فعله هو استخدام متغير وسيط. سيكون هذا المتغير مستقلاً من حيث النوع ثم سيتم التحقق منه مقابل نوع الرجوع:
const createObject = async (): Promise<MyType> => {
await Promise.resolve();
let result: MyType = {
async foo() {
await this.bar();
// do something else
},
async bar() {
await Promise.resolve();
// do something here
}
};
return result;
};
interface MyType {
foo: () => Promise<void>;
bar: () => Promise<void>;
}
رابط الملعب
