I'm currently adding types in our Angular project, using Cordova file plugin. In order to list all the directories at a specific path, we use the following code :
const directory: any = await new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
I know that directory
is a DirectoryEntry
object, which is an interface extending Entry
. My problem is that using const directory: DirectoryEntry
makes TypeScript complain.
Impossible to assign type 'Entry' to type 'DirectoryEntry | PromiseLike<DirectoryEntry>'.
How can I properly do this ? I know that I could simply let directory
be any
and cast it latter, but still, I'm curious to see how this problem could be solved.
Thanks a lot for all your answers.
You should be able to pass the type parameter to the promise constructor - like so:
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
Edit: Ok - I see your problem is that resolveLocalFileSystemURL is telling you that the callback passed to it's second parameter is going to be called with Entry
, not DataDirectory
.
Because resolveLocalFileSystemURL will pass an object to resolve, it can't tell if it's a directory or a file (and - your file structure might change).
If you want to ignore the warning, I'd say something like:
const entry = await new Promise<Entry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
// We know this path is a directory
const directory = entry as DirectoryEntry;
or
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, entry => resolve(entry as DirectoryEntry), reject);
});
A safer alternative is to actually check it is a directory, and handle as appropriate, using a type-predicate:
function isDirectory(entry: Entry): entry is DirectoryEntry {
return entry.isDirectory;
}
const entry = await new Promise<Entry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
if (isDirectory(entry)) {
// In this scope, TS has now narrowed entry to DirectoryEntry safely
}