Reputation: 141
typescript 3.1.2
I have searched through many stack overflow questions and online articles, and I've seen the same types of answers many times to questions about modifying existing typescript classes such as String
and Array<T>
, but I can't seem to get this working for the Promise<T>
class.
I've already read through all of these, no luck:
How to define global function in TypeScript?
How to add file with extending prototype in Typescript
How to extend String Prototype and use it next, in Typescript?
Cypress Custom TypeScript Command is not a Function
Here's my current code (I've tried many variations):
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}`);
}]);
}
(I've tried adding export { }
in Promise.ts, it doesn't help)
another.ts
import '../theDir/Promise'
anAsyncMethod().catchWrapper();
This all compiles but I continually get runtime errors:
UnhandledPromiseRejectionWarning: TypeError: anAsyncMethod().catchWrapper is not a function
Is my implementation of catchWrapper() not being matched up to the declaration of the interface by the compiler?
Any ideas on how to fix this?
Upvotes: 2
Views: 1199
Reputation: 141
The goal here was to have the extension method in a lib and use it in other apps. After messing around with it for a while I ended up using this solution. Leaving any part of it out causes runtime errors.
By putting both the declaration and definition in the .ts file and then importing the file (anywhere..!) in the lib my other project is then able to use the extension method as soon as it imports anything from the lib.
Here's what the final code looks like:
In the lib project:
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'
In the main app:
// 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*/ }`
Upvotes: 3
Reputation: 2822
Try changing the content or Promise.d.ts
to this:
declare interface Promise<T> {
catchWrapper (): Promise<T>;
}
Also should not need to import the .d.ts
if it is located either in your rootDir
or in one of typeRoots
specified in the config file.
Upvotes: 1