由于类型已过时,因此我正在尝试为正在使用的包修改类型声明。我可以很好地调整大多数内容,但是似乎无法解决一个错误,那就是该函数返回的接口的属性。
这是一个代码示例。我已经剥离了代码,我敢肯定与该问题无关,以便于阅读。如果您觉得缺少某些可能有助于理解该问题的信息,请告诉我。
declare namespace renderContent {
type renderContentCallback = (
eventOrImage: Event | HTMLCanvasElement | HTMLImageElement,
data?: MetaData
) => void;
interface ImageHead {
imageHead?: ArrayBuffer | Uint8Array;
}
interface MetaData extends ImageHead {
//...
}
interface PromiseData extends MetaData {
image: HTMLCanvasElement | HTMLImageElement;
}
interface BasicOptions {
//...
}
type renderContentOptions = BasicOptions
}
interface renderContent {
(
file: File | Blob | string,
/* If options are defined instead of a callback function, the next argument will be skipped and the function will return a promise */
callbackOrOption?: renderContent.renderContentCallback | renderContent.renderContentOptions,
options?: renderContent.renderContentOptions
): HTMLImageElement | FileReader | Promise<renderContent.PromiseData> | false;
}
declare const renderContent: renderContent;
export = renderContent;
然后当我在代码中像这样使用它时:
const { image } = await renderContent(file, options);
我收到一条错误消息:
类型“ false”上不存在属性“图像” | HTMLImageElement | FileReader | PromiseData'
在我看来,错误消息中列出的 PromiseData 接口中似乎已明确定义了它。那我想念什么?
答案 0 :(得分:3)
问题是,打字稿无法确定renderContent
返回的类型将是Promise<renderContent.PromiseData>
。实际上,对于打字稿,类型也可以是FileReader
或HtMLImageElement
...
这些类型没有键image
,这就是为什么出现此错误的原因。
我想您认为使用关键字await
会使打字稿猜测Promise<renderContent.PromiseData>
是正确的返回类型,但不幸的是不是。
为了告诉打字稿您在等待什么,请使用关键字as
,例如:
const { image } = await (renderContent(_) as Promise<renderContent.PromiseData>);
它可能有效,但有副作用。例如:
如果您使用类似的功能:
const data = renderContent(false as unknown as File);
使用打字稿,您最多可以调用data.readAsArrayBuffer
到data.height
,这是错误的。因为renderContent
返回一个HTMLCanvasElement
,所以返回一个HTMLImageElement
。
考虑到所有问题,更好的解决方案是准确描述renderContent
调用方案的外观:
type possibilityA = (
file: File | Blob | string,
options: renderContent.renderContentOptions
) => Promise<renderContent.PromiseData>;
type possibilityB = (
file: File | Blob | string,
callback: renderContent.renderContentCallback,
) => HTMLImageElement | FileReader | false;
type possibilityC = (
file: File | Blob | string,
callback: renderContent.renderContentCallback,
options: renderContent.renderContentOptions
) => HTMLImageElement | FileReader | false;
type renderContent = possibilityA & possibilityB & possibilityC;
declare const renderContent: renderContent;
(async() => {
const data = await renderContent('foo', { });
})();
在这种情况下,打字稿将根据您提供的参数来选择适当的重载,该参数将相应地定义data
的类型。