当我要调用的函数需要父类型 A 时,如何使用子类型 B 创建一个新的 Promise
How to create a new Promise with child type B when the function I want to call expects parent type A
我目前正在使用 Cordova 文件插件在我们的 Angular 项目中添加类型。为了列出特定路径下的所有目录,我们使用以下代码:
const directory: any = await new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
我知道directory
是一个DirectoryEntry
对象,是扩展Entry
的接口。我的问题是使用 const directory: DirectoryEntry
会使 TypeScript 抱怨。
Impossible to assign type 'Entry' to type 'DirectoryEntry | PromiseLike<DirectoryEntry>'.
我怎样才能正确地做到这一点?我知道我可以简单地让 directory
成为 any
并将其转换为后者,但我仍然很好奇这个问题是如何解决的。
非常感谢您的所有回答。
您应该能够将类型参数传递给 promise 构造函数 - 就像这样:
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
编辑:好的 - 我看到你的问题是 resolveLocalFileSystemURL 告诉你传递给它的第二个参数的回调将用 Entry
调用,而不是 DataDirectory
.
因为 resolveLocalFileSystemURL 将传递一个对象来解析,所以它无法判断它是一个目录还是一个文件(并且 - 您的文件结构可能会改变)。
如果你想忽略警告,我会这样说:
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;
或
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, entry => resolve(entry as DirectoryEntry), reject);
});
一个更安全的替代方法是实际检查它是一个目录,并使用 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
}
我目前正在使用 Cordova 文件插件在我们的 Angular 项目中添加类型。为了列出特定路径下的所有目录,我们使用以下代码:
const directory: any = await new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
我知道directory
是一个DirectoryEntry
对象,是扩展Entry
的接口。我的问题是使用 const directory: DirectoryEntry
会使 TypeScript 抱怨。
Impossible to assign type 'Entry' to type 'DirectoryEntry | PromiseLike<DirectoryEntry>'.
我怎样才能正确地做到这一点?我知道我可以简单地让 directory
成为 any
并将其转换为后者,但我仍然很好奇这个问题是如何解决的。
非常感谢您的所有回答。
您应该能够将类型参数传递给 promise 构造函数 - 就像这样:
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, resolve, reject);
});
编辑:好的 - 我看到你的问题是 resolveLocalFileSystemURL 告诉你传递给它的第二个参数的回调将用 Entry
调用,而不是 DataDirectory
.
因为 resolveLocalFileSystemURL 将传递一个对象来解析,所以它无法判断它是一个目录还是一个文件(并且 - 您的文件结构可能会改变)。
如果你想忽略警告,我会这样说:
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;
或
const directory = await new Promise<DirectoryEntry>((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + path, entry => resolve(entry as DirectoryEntry), reject);
});
一个更安全的替代方法是实际检查它是一个目录,并使用 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
}