Cannot find name 'Entry'

I made a simple function to unzip a selected file to a temp folder, check if contains a file with specific extension, then return the Entry object of this file:

1unzipAndCheckKML(zipFilePath:string, extractionPath:string, extractionFolder:string): Promise<Entry> {
2	return this.zip.unzip(zipFilePath, extractionPath+extractionFolder).then(() => {
3		return this.file.listDir(extractionPath, extractionFolder).then(entryList => {
4			console.log(entryList);
5			return entryList.find((fileEntry) => {
6				let fileExtension = fileEntry.name.split('.').pop();
7				if (fileExtension === 'kml') {
8					return fileEntry;
9				}
10			});
11		})			
12	});
13}

The problem I’m facing is that the find function is returning a boolean value! Well… in fact is returning an Entry object, but it’s saying that is a boolean:

line 1 → error TS2304: Cannot find name ‘Entry’.
line 5 → error TS2345: Argument of type ‘(this: void, fileEntry: Entry) => Entry’ is not assignable to parameter of type ‘(value: Entry, index: number, obj: Entry) => boolean’.
Type ‘Entry’ is not assignable to type ‘boolean’.

If I try to declare the type of arrow function as Entry:
entryList.find((fileEntry): Entry => {
, I get this problem:

Cannot find name ‘Entry’.

If I try to change the iteration method I got this same error.


Zip | File

I ended up finding it necessary to import the Entry type together with File:
import { File, Entry } from '@ionic-native/file/ngx';

and then:

unzipAndCheckKML(zipFilePath:string, extractionPath:string, extractionFolder:string): Promise<Entry> {
  return this.zip.unzip(zipFilePath, extractionPath+extractionFolder).then(() => {
    return this.file.listDir(extractionPath, extractionFolder).then(entryList => {
      for (let fileEntry of entryList) {
        let fileExtension = fileEntry.name.split('.').pop();
        if (fileExtension === 'kml') {
          return fileEntry;
        }
      }
    })      
  });
}

However find() continued to bring me the response as a boolean.

Since the thread’s already marked solved, maybe what I’m going to say isn’t very important, but:

To translate this into pseudo-English, tsc is saying:

I wanted a function that takes an Entry, a numeric index, and an array of Entry and returns me a boolean, but you gave me a function that ignores its context, takes only a single Entry and (maybe) returns an Entry. Puke!

Unpack your arrow function, ignoring the execution context issue (i.e. what this is bound to), because you’re not using this inside there.

finder(fileEntry: Entry): Entry {
  let fileExtension = fileEntry.name.split('.').pop();
  if (fileExtension === 'kml') {
    return fileEntry;
  }
  // you didn't write this, but it's what JavaScript does when 
  // functions don't return anything
  return undefined;
}

How to write it in a format that find is wanting:

return entryList.find(fileEntry => {
  let fileExtension = fileEntry.name.split(".").pop();
  return fileExtension === "kml";
});

That’s going to have a signature of (this: void, fileEntry: Entry, ignoredIndex: number, ignoredObj: Entry[]) => boolean, which should be compatible.

1 Like

Very well explained, thank you very much! At least I could understand why this problem happened. I ended up doing it the other way because I didn’t know it was possible to return the object with just a condition syntax like you did:

return fileExtension === "kml";

Until now I thought it was necessary to make the return of the object evident.

It isn’t, but find doesn’t want you to return the object: it already knows what the object is. It just wants you to give it a thumbs up or down as to whether that object passes your filter. The API is modeled on JavaScript’s Array.find, which just wants its filter to return a boolean indicating whether the given object passes the test.

1 Like