【如此之白】OpenHarmony API声明文件探究 原创 精华
使用DevEco开发OpenHarmony应用的小伙伴是不是经常发现,明明OpenHarmony提供了接口支持,但是IDE却没有任何提示,甚至出现报错,需要使用忽略大法@ts-ignore
才能使开发流程不被堵塞。
那么跟着我一起来探究下OpenHarmony的声明文件吧。
查看OpenHarmony API的声明文件也是辅助了解OpenHarmony接口能力的好方法。(但API不一定是全部被实现的)
API声明文件公共仓
公共仓地址:https://gitee.com/openharmony/interface_sdk-js/tree/master
- 选择当前系统对应的版本,这里我的版本是
3.1beta
。
- 进入
api
文件夹即可看到声明文件。
DevEco声明文件
文件位置:
[OpenHarmony SDK文件夹]\ets\3.1.0.0\api\common
[OpenHarmony SDK文件夹]\js\3.1.0.0\api\phone
typescript声明文件
声明文件以 .d.ts
结尾,里面主要用来定义类型。
TypeScript 身为 JavaScript 的超集,自然需要考虑到如何让 JS 库也能定义静态类型。所以TypeScript 提出了DefinitelyTyped。
DefinitelyTyped就是让你把 “类型定义文件(*.d.ts)”,配合编辑器(或插件),就能够检测到 JS 库中的静态类型。
export
和import
声明会导出或导入目标的所有含义。
如何读声明文件
我们来看@ohos.resourceManager.d.ts
这个文件。
本地:[OpenHarmony SDK文件夹]\ets\3.1.0.0\api\common@ohos.resourceManager.d.ts
同时可以结合HarmonyOS的文档进行阅读:
declare
声明变量使用关键字declare
来表示声明其后面的全局变量
的类型。
declare namespace resmgr {
...
}
export default resmgr;
引入该模块。
import resmgr from '@ohos.resourceManager';
引入该模块会发现报错了。
查看错误:
我们去到SDK文件夹下检查文件@ohos.resourceManager.d.ts
,会发现末尾少写了个大括号。
...
} //这里添上一个大括号
}
export default resmgr;
重启DevEco,发现报错不见了,那么我们继续。
namespace
命名空间定义了标识符的可见范围。
一般来说,如果我们需要在外部可以调用resmgr
中的类和接口,则需要在类和接口添加export
关键字。
但是resmgr
在DevEco中反而找不到任何提示。推测对于DevEco,namespace
内使用export
是错误的。
我们将@ohos.resourceManager.d.ts
中namespace
中的export
关键字全部去掉,重启DevEco,现在提示都出来了。
我们可以看到一般在命名空间内会定义以下几种类型。
// 枚举
enum Direction {
...
}
// 类
class Configuration {
...
}
// 接口
interface ResourceManager {
...
}
// 方法
function getResourceManager(bundleName: string, callback: AsyncCallback<ResourceManager>);
函数重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
在声明文件中我们可以看到这样的一个方法:
// 获取当前应用的资源管理对象,使用callback形式返回ResourceManager对象。
export function getResourceManager(callback: AsyncCallback<ResourceManager>);
// 获取当前应用的资源管理对象,使用Promise形式返回ResourceManager对象。
export function getResourceManager(): Promise<ResourceManager>;
实际上我们可以看到这两个方法实现的是同一个能力,只是使用形式不同。
这里要特别说明一下在所有声明文件当中随处可见的两个接口:
- AsyncCallback<T>
- Promise<T>
AsyncCallback<T>
接口定义
interface AsyncCallback<T> {
(err: Error, data: T): void;
}
调用getResourceManager(callback: AsyncCallback<ResourceManager>)
resourceManager.getResourceManager((error, mgr) => {
//成功时, error返回undefined
if (error != null) {
console.log("error occurs" + error);
return;
}
console.log("mgr ready")
});
调用getResourceManager(): Promise<ResourceManager>
resourceManager.getResourceManager().then(mgr => {
console.log("mgr ready")
}).catch(error => {
console.log("error occurs" + error);
});
// 或者
try{
let mgr = await resmgr.getResourceManager()
}catch(error){
console.log("error occurs" + error);
}
basic.d.ts
在这个文件里定义了几个常用接口
export interface Callback<T> {
(data: T): void;
}
export interface ErrorCallback<T extends Error = BusinessError> {
(err: T): void;
}
export interface AsyncCallback<T> {
(err: BusinessError, data: T): void;
}
export interface BusinessError extends Error {
code: number;
}
我们来看@ohos.bundle.d.ts
文件
// 导入basic声明接口
import { AsyncCallback, Callback } from './basic';
...
// 声明方法
function getBundleInfo(bundleName: string, bundleFlags: number, callback: AsyncCallback<BundleInfo>): void;
为DevEco添加声明文件
OpenHarmony支持显示设备属性@ohos.display
,但是却没有为display添加声明文件。
那么我们自己来写一个@ohos.display.d.ts
文件。
首先在[OpenHarmony SDK文件夹]\ets\3.1.0.0\api\common
新建文件@ohos.display.d.ts
。
导出一个命名空间display
declare namespace display {
}
export default display;
通过之前使用测试,我们发现OpenHarmony只支持display的getDefaultDisplay
方法,该方法使用Promise形式返回一个Display
对象。
Display
对象只支持两个可读属性width
和height
。
interface Display {
readonly width: number;
readonly height: number;
}
getDefaultDisplay
方法的定义
function getDefaultDisplay(): Promise<Display>;
那么完整的@ohos.display.d.ts
declare namespace display {
function getDefaultDisplay(): Promise<Display>;
interface Display {
readonly width: number;
readonly height: number;
}
}
export default display;
保存,重新启动DevEco。
注意:
- 不要直接拷贝HarmonyOS SDK的
@ohos.display.d.ts
文件,因为太多OpenHarmony没有支持了。- js开发则需要在
[OpenHarmony SDK文件夹]\js\3.1.0.0\api\phone
添加@ohos.display.d.ts
文件
现在报错没有了,来使用API看看吧。
提示都出来啦~
打印一个分辨率在开发板上试试:
display.getDefaultDisplay().then(dis => {
console.log('[DEMO]width:' + dis.width)
console.log('[DEMO]height:' + dis.height)
})
非常完整的教程,必须收藏一波
666
厉害啦
好文,值得顶