تایپاسکریپت - مشکل در اضافه کردن متد جدید به پروتوتایپ Promise


تایپاسکریپت ۳.۱.۲

من بسیاری از سوالات سایت استک اورفلو و مقالات آنلاین را بررسی کردهام و بارها همان نوع پاسخها را به سوالات مربوط به تغییر کلاسهای موجود تایپاسکریپت مانند String و Array<T> دیدهام، اما به نظر نمیرسد که بتوانم این کار را برای کلاس Promise<T> عملی کنم.

من قبلاً همه اینها را خواندهام، هیچ نتیجهای نداشته:

چگونه یک تابع سراسری در تایپاسکریپت تعریف کنیم؟

چگونه فایل را با گسترش پروتوتایپ در تایپاسکریپت اضافه کنیم

چگونه پروتوتایپ رشته را گسترش دهیم و بعد در تایپاسکریپت از آن استفاده کنیم؟

دستور سفارشی تایپاسکریپت سایپرس یک تابع نیست

گسترش آرایه در تایپاسکریپت

در اینجا کد فعلی من است (من چندین حالت مختلف را امتحان کردهام):

Promise.d.ts

declare global {
    export interface Promise<T> {
        catchWrapper(): Promise<T>;
    }
}

Promise.ts

Promise.prototype.catchWrapper = function<T>(this: Promise<T>): Promise<T> {
    return Promise.prototype.catch.apply(this, [e => {
        console.log(`catch wrapper. ${e}`);
        }]);
    }

(من سعی کردهام export { } را در Promise.ts اضافه کنم، اما کمکی نکرده است)

دیگری.ts

import '../theDir/Promise'

anAsyncMethod().catchWrapper();

همه اینها کامپایل میشوند اما من مدام خطاهای زمان اجرا دریافت میکنم:

UnhandledPromiseRejectionWarning: TypeError: anAsyncMethod().catchWrapper is not a function

آیا پیادهسازی من از catchWrapper() توسط کامپایلر با اعلامیهٔ اینترفیس مطابقت داده نمیشود؟

ایدهای دارید که چطور این را درست کنیم؟

پاسخ شماره ۱

هدف اینجا این بود که متد توسعه را در یک کتابخانه داشته باشم و از آن در برنامههای دیگر استفاده کنم. بعد از دستکاری آن برای مدتی، در نهایت از این راه حل استفاده کردم. حذف هر بخشی از آن باعث بروز خطاهای زمان اجرا میشود.

با قرار دادن هم اعلامیه و هم تعریف در فایل .ts و سپس وارد کردن فایل (هر جایی..!) در کتابخانه، پروژه دیگر من قادر است از روش توسعه یافته به محض وارد کردن هر چیزی از کتابخانه استفاده کند.

اینجا شکل نهایی کد به این صورت است:

در پروژه lib:

Promise.ts

Promise.prototype.catchExtension = function<T>(this : Promise<T>): Promise<T> {
    return Promise.prototype.catch.apply(this, [() => { /*do stuff*/ }]);
}

declare global {
    interface Promise<T> {
        catchExtension(): Promise<T>;
    }
}
export { }

lib.ts

import './Promise';
export { } from './Promise';
// The rest of the exports
export { Example } from './Example'

در برنامه اصلی:

// Import anything from lib
import { Example } from '@mylib'
// import { } from '@mylib' <--- doesn't work

const x: Promise<string> = new Promise( (resolve, reject) => { reject(); });
x.catchExtension();
// It works! We end up in `() => { /*do stuff*/ }`

پاسخ شماره ۲

سعی کنید محتوا یا Promise.d.ts را به این تغییر دهید:

declare interface Promise<T> {
  catchWrapper (): Promise<T>;
}

همچنین نیازی به وارد کردن .d.ts نخواهد بود اگر در rootDir شما یا در یکی از typeRoots مشخص شده در فایل پیکربندی قرار داشته باشد.