首页 > 其他分享 >使用napi实现ts枚举类型

使用napi实现ts枚举类型

时间:2024-07-05 17:41:58浏览次数:14  
标签:EnumClass VAL ts enumVals 枚举 env enumKeys napi

在napi模块中定义枚举类型

枚举类型不是js的原生类型,它是ts中独有的语法,但是napi方法仅支持操作js对象。

下文将提供一个demo用来实现一个js的enum类。

分析ts枚举类的实现方式

定义一个ts枚举类

TypeScript 代码如下:

enum EnumClass {
    VAL_A = 0,
    VAL_B,
    VAL_C,
}

使用tsc命令将ts文件转为js文件,生成的js文件内容如下:

var EnumClass;
(function (EnumClass) {
    EnumClass[EnumClass["VAL_A"] = 0] = "VAL_A";
    EnumClass[EnumClass["VAL_B"] = 1] = "VAL_B";
    EnumClass[EnumClass["VAL_C"] = 2] = "VAL_C";
})(EnumClass || (EnumClass = {}));

分析代码,tsc 转换后的代码逻辑如下:

  1. 定义一个全局变量 EnumClass
  2. 构造一个匿名函数,该函数接受一个入参,入参类型经推断应为Object。函数逻辑如下:
    1. 为Object EnumClass定义了三个 keyenum的keyvalueenum的value 的属性。
    2. 为Object EnumClass定义了三个 valueenum的keykeyenum的value 的属性。
  3. 将全局变量EnumClass传递到上述函数,若全局变量EnumClass为undefined或null等值(即或语句前条件为false)则使其为空Object。

根据以上步骤,不难发现,enum在js中实际上是一个key、value互相作为key/value的Object。

使用napi方法进行实现js枚举类

定义一个C/C++的枚举类,其将作为js枚举类在Native枚举类的映射

enum EnumClass { 
    VAL_A = 0,
    VAL_B,
    VAL_C,
};

创建一个js Object, 用以容纳枚举类的内容

napi_value enumObject = nullptr;
napi_create_object(env, &enumObject);

定义两个下文将会使用到的宏,减少模板代码

// 按照枚举值的 key 和 value 创建对应的 napi value
#define GEN_ENUM_KV(env, enum, key, jsKey, jsVal) do {                 \
    napi_create_string_utf8((env), #key, NAPI_AUTO_LENGTH, &(jsKey));  \
    napi_create_int32((env), enum::key, &(jsVal));                     \
} while (0)

// 用以减少定义 napi_property_descriptor 模板代码
#define SET_ENUM_KV(jsKey, jsVal)                                                  \
    { nullptr, (jsKey), nullptr, nullptr, nullptr, (jsVal), napi_default, nullptr }

创建并初始化所需的 napi_value

napi_value enumKeys[3] = {nullptr};  // 3: num of EnumClass
napi_value enumVals[3] = {nullptr};  // 3: num of EnumClass

GEN_ENUM_KV(env, EnumClass, VAL_A, enumKeys[0], enumVals[0]);
GEN_ENUM_KV(env, EnumClass, VAL_B, enumKeys[1], enumVals[1]);
GEN_ENUM_KV(env, EnumClass, VAL_C, enumKeys[2], enumVals[2]);  // 2: index array

枚举类的实现应用到js Object

// 创建一个 napi_property_descriptor 数组,用以容纳js枚举值

napi_property_descriptor desc[] = {
    NAPI_SET_VALUE(enumKeys[0], enumVals[0]),
    NAPI_SET_VALUE(enumKeys[1], enumVals[1]),
    NAPI_SET_VALUE(enumKeys[2], enumVals[2]),  // 2: index array
};

napi_define_properties(env, enumObject, sizeof(desc) / sizeof(desc[0]), desc);

napi_set_property(env, enumObject, enumVals[0], enumKeys[0]),
napi_set_property(env, enumObject, enumVals[1], enumKeys[1]),
napi_set_property(env, enumObject, enumVals[2], enumKeys[2]),  // 2: index array

完整示例代码

Native侧 C++ 代码。

enum EnumClass { 
    VAL_A = 0,
    VAL_B,
    VAL_C,
};

#define GEN_ENUM_KV(env, enum, key, jsKey, jsVal) do {                 \
    napi_create_string_utf8((env), #key, NAPI_AUTO_LENGTH, &(jsKey));  \
    napi_create_int32((env), enum::key, &(jsVal));                     \
} while (0)

#define NAPI_SET_VALUE(jsKey, jsVal)                                                  \
    {nullptr, (jsKey), nullptr, nullptr, nullptr, (jsVal), napi_default, nullptr}

static SomeFunction(napi_env env /* args... */)
{
    // ... ...
    napi_value enumObject = nullptr;
    napi_create_object(env, &enumObject);

    napi_value enumKeys[3] = {nullptr};  // 3: num of EnumClass
    napi_value enumVals[3] = {nullptr};  // 3: num of EnumClass

    GEN_ENUM_KV(env, EnumClass, VAL_A, enumKeys[0], enumVals[0]);
    GEN_ENUM_KV(env, EnumClass, VAL_B, enumKeys[1], enumVals[1]);
    GEN_ENUM_KV(env, EnumClass, VAL_C, enumKeys[2], enumVals[2]);  // 2: index array

    napi_property_descriptor desc[] = {
        NAPI_SET_VALUE(enumKeys[0], enumVals[0]),
        NAPI_SET_VALUE(enumKeys[1], enumVals[1]),
        NAPI_SET_VALUE(enumKeys[2], enumVals[2]),  // 2: index array
    };

    napi_set_property(env, enumObject, enumVals[0], enumKeys[0]),
    napi_set_property(env, enumObject, enumVals[1], enumKeys[1]),
    napi_set_property(env, enumObject, enumVals[2], enumKeys[2]),  // 2: index array

    napi_define_properties(env, enumObject, sizeof(desc) / sizeof(desc[0]), desc);
    // ... ...
}

对应的枚举类的 .d.ts 描述文件。

export enum EnumClass {
    VAL_A = 0,
    VAL_B,
    VAL_C,
}

与上述逻辑相匹配的js代码。

const EnumClass = {
    0: "VAL_A",
    1: "VAL_B",
    2: "VAL_C",

    VAL_A: 0,
    VAL_B: 1,
    VAL_C: 2,
}

标签:EnumClass,VAL,ts,enumVals,枚举,env,enumKeys,napi
From: https://www.cnblogs.com/milkpotatoes/p/18286305

相关文章

  • echarts中Label标签与数据项颜色设置为同一种颜色
    echarts5中默认标签颜色不会跟数据项颜色保持一致,而是全都是黑色。想要实现label颜色和它的数据项颜色一致,需要手动继承颜色,设置label{color:'inherit'}即可解决label标签颜色与数据项颜色一致。  https://echarts.apache.org/examples/zh/editor.html?c=pie-simple注意:......
  • zustand Auto Generating Selectors/ts-pattern/swr/TypeScript在monorepo项目中实现
    zustandAutoGeneratingSelectorshttps://docs.pmnd.rs/zustand/guides/auto-generating-selectorsts-pattern替换匹配组件代swrTypeScript在monorepo项目中实现即时更新https://colinhacks.com/essays/live-types-typescript-monorepomonorepodocker项目名:my-project......
  • mainCRTStartup WinMainCRTStartup
    assumecs:codesg,ds:datas;str字符必须是13位,所以中间加了两个空格,网上很多代码也避开了这个问题,都是通过加空格,拼写错误,反正加个占位符;否则会输出一堆乱码,实在想不明白是什么原因datassegmentstrdb'HelloWorld!','$'datasendscodesgsegmentmovax,datas......
  • bootstrap-fileinput 使用
    参考文档:http://www.bootstrap-fileinput.com/options.html视频和图片上传和展示:<divclass="form-grouprow"><labelfor="video_path"class="col-sm-2col-form-label"><spanclass="text-danger">*<......
  • STM32F1+HAL库+FreeTOTS学习5——内核中断管理及中断控制函数
    STM32F1+HAL库+FreeTOTS学习5——中断管理和临界段代码保护中断简介中断优先级寄存器拓展FreeRTOS中PendSV和Systick中断优先级配置三个中断屏蔽寄存器FreeRTOS中断管理函数代码验证上一期我们学习了FreeRTOS中任务挂起与恢复,在中断服务程序中恢复任务过程中,尤其强调......
  • [1022] Activate specific apps using keyboard shortcuts
    Thisisaverygoodone!!! TaskbarShortcutKeys:Ifanappispinnedtoyourtaskbar,youcanusethefollowingshortcut:PressWin+1toactivatethefirstprogramonthetaskbar(orlaunchitifit’snotopen).Similarly,Win+2activatesthesec......
  • 做了一款服务网络安全的多端系统。内置AI(gpt4o)/ai绘画(sd)/ChatTTS,无需登陆免费使用
    上一篇魔盒介绍文章已被我删除,因为本次重新做了产品定位,之前定位有点混乱先上链接之前有个哥们说做了app还不如先做网站,因为不方便下载,这次做了哈。重点:里面有gpt4o,充了几十美元反正也用不完,给大家用了网页端:https://mgb.abyssdawn.com/H5端:https://mgb-h5.abyssdaw......
  • 做了一款服务网络安全的多端系统。内置AI(gpt4o)/ai绘画(sd)/ChatTTS,无需登陆免费使用
    上一篇魔盒介绍文章已被我删除,因为本次重新做了产品定位,之前定位有点混乱先上链接之前有个哥们说做了app还不如先做网站,因为不方便下载,这次做了哈。重点:里面有gpt4o,充了几十美元反正也用不完,给大家用了网页端:https://mgb.abyssdawn.com/H5端:https://mgb-h5.abyssdawn.co......
  • 邮件显示统计图表echarts-java+phantomjs实现
    邮件显示统计图表echarts-java+phantomjs实现项目背景是产品业务上的订阅推送,纯java后端实现,通过邮件将统计报表发送给用户。这里会涉及一些关键点:首先是统计图表的生成,我们采用常见的echarts,简单易用,支持图表类型丰富美观;java后端实现可使用echarts-java来实现图表的生成......
  • GreatSQL 中 Insert 慢是什么情况?
    GreatSQL中Insert慢是什么情况?背景概述客户反映,业务上某张表的Insert操作速度很慢,单条Insert语句的最大执行时间超过了5秒。在收到客户问题后,我们仔细检查了数据库状态以及主机的负载情况,发现目前一切正常,并没有发现数据库故障或主机负载过高导致insert操作变慢的问题......