I've been working on a new project using NodeJS. Again, I'm using TypeScript for added safety, which means I have to (and want to) play nice with the type system. This code also uses ECMAScript 6 Promises for asynchronous database queries, and I ran into some funny (like funny uh-oh) problems here. But also solutions, so I thought I'd share.
Promises are templated with the type of value they return in success, i.e. what's passed to resolve
, but if you reject
a promise, can the Typescript compiler figure out what template type it is? Let's say I have code that looks like this, where I'm wrapping the error from the database library with my own error type.
query.execute().then(function(result : RecordSet) : Promise<MyResults>
{
// compiler can deduce it's a Promise<MyResults> by the parameter to
// resolve()
return Promise.resolve(new MyResults(result));
}, function(err : any) : Promise<MyResults>
{
// Promise is only templated on the success type, so can it figure out the
// template type from a reject call?
return Promise.reject(new MyError(ERROR_TYPE_GENERIC, err));
});
This produces a Typescript error: TS2322: Type 'Promise<void>' is not assignable to type 'Promise<MyResults>'
. So Promise.reject
implicitly returns a Promise<void>
object. Can I return one with a different type? Here's an attempt:
return Promise<MyResults>.reject(new MyError(ERROR_TYPE_GENERIC, err));
error TS1005: '(' expected.
error TS1005: ')' expected.
That's a syntax error. Guess that wasn't it. After much fumbling, I figured it out, so I wanted to share here:
return Promise.reject<MyResults>(new MyError(ERROR_TYPE_GENERIC, err));
OK, thanks, totally arbitrary syntax. I also think it's interesting that the Promise
object isn't templated with both the type of the value and the type of the error, for extra safety.
0 comments:
Post a Comment