keldar
keldar

Reputation: 6252

TypeScript error with Promise.reject

Why do I receive the following compilation error with this TypeScript method which I wrote:

getFile(path: string): Promise<FileEntry> {
  return this.file.resolveLocalFilesystemUrl(path)
    .then(entry => {
      if (entry.isFile) {
        return <FileEntry>entry;
      } else {
        let err = new FileError(13);         
        err.message = 'input is not a file';
        return Promise.reject(err);
      }
    });
}

I get the error:

Argument of type '(entry: Entry) => Promise<never> | FileEntry' is not assignable to parameter of type '(value: Entry) => PromiseLike<never>'. Type 'Promise<never> | FileEntry' is not assignable to type 'PromiseLike<never>'. Type 'FileEntry' is not assignable to type 'PromiseLike<never>'. Property 'then' is  missing in type 'FileEntry'.

The definition for resolveLocalFilesystemUrl is as follows:

resolveLocalFilesystemUrl(fileUrl: string): Promise<Entry>;

FileEntry is a subclass of Entry, hence the casted return. However, the error is around Promise.reject.

If I change my reject line to the following, it works:

return Promise.reject<FileEntry>(err);

Do I need to return Promise.reject(...) and what is the correct implementation?

Upvotes: 0

Views: 9280

Answers (3)

Aziz Khambati
Aziz Khambati

Reputation: 368

You can try wrapping the return entry with a Promise.resolve. This solved when I had a similar error.

getFile(path: string): Promise<FileEntry> {
  return this.file.resolveLocalFilesystemUrl(path)
    .then(entry => {
      if (entry.isFile) {
        // See this
        return Promise.resolve(<FileEntry>entry);
      } else {
        let err = new FileError(13);         
        err.message = 'input is not a file';
        return Promise.reject(err);
      }
    });
}

You won't have to write the verbose new Promise((resolve, reject) => {}) because your underlying this.file.resolveLocalFilesystemUrl already returns a Promise and you can chain on it. (Which I feel is the correct way.)

Upvotes: 0

Daniel
Daniel

Reputation: 2053

To return a promise you create a new Instance of a promise and return this instance. The constructor takes a function that receives the resolve and reject callbacks you should call, when your logic succeeds or fails.

To let your promise "return" your result, you don't write return result, but call resolve(result).

getFile(path: string): Promise<FileEntry> {
  return new Promise<FileEntry>((resolve, reject) => {
    // Your logic here.
    // call resolve() on success
    // or reject() on failure
  });
}

So in your case it should look like the following:

getFile(path: string): Promise<FileEntry> {
  return new Promise<FileEntry>((resolve, reject) => {
    this.file.resolveLocalFilesystemUrl(path)
    .then(entry => {
      if (entry.isFile) {
        resolve(<FileEntry>entry); // Success
      } else {
        let err = new FileError(13);         
        err.message = 'input is not a file';
        reject(err); // Error
      }
    });
  });
}

If you want to learn more about promises read for example here: https://developers.google.com/web/fundamentals/primers/promises

Upvotes: 5

Martin Nuc
Martin Nuc

Reputation: 5764

You shouldn't really return a resolved or rejected promise inside of your promise chain.

When you want to indicate an error you should just throw an error:

else
   let err = new FileError(13);         
   err.message = 'input is not a file';
   throw err;

Upvotes: 1

Related Questions