跳过主要内容
移动 Capacitor

TypeScript API 示例:Capacitor 和 Capgo

探索一个实用的 TypeScript API 示例,了解 Capacitor 插件和 Capgo 更新的使用方法。掌握类型化接口、监听模式和实现策略。

TypeScript API 示例:Capacitor 和 Capgo

每个坚实的 TypeScript API 示例 for Capacitor begins the same way: with a typed plugin interface. Spell out your methods, options, and Promise results explicitly, and your web code and the native layer share one contract that TypeScript actually enforces.

内容概览

构建一个强类型的Capacitor插件接口

接口描述了API您的webcode看到的内容。后端的本机实现必须遵守这个契约——并且在您的应用程序运行之前,TypeScript会检查方法名、参数和返回值。

import { registerPlugin } from ‘@capacitor/core’;

export interface DeviceStatus { 在线: boolean; batteryLevel?: number; }

export interface DevicePlugin {\ngetStatus(): Promise}; setLabel(options: { label: string }): Promise<{ saved: boolean }>;

export const Device = registerPlugin(‘Device’);

(‘Device’);

  • 那些行代码中有很多事情: 明确的返回类型
  • 让每个结果都可预测。 类型化的选项对象
  • 在编译时捕捉到缺失或拼写错误的属性。 基于Promise的方法
  • 模拟原生工作,异步完成。 registerPlugin 一个通用函数 是连接 web API 和原生桥的关键部分。
  • 接口 文档描述了契约而不添加任何运行时 code。

每个调用站点都得到相同的处理:

const status = await Device.getStatus(); console.log(status.online);

await Device.setLabel({ label: ‘生产环境’ });

交换 { label: 'Production' } 而 { name: 'Production' } 并且编译器在这一点上标记它。这样做比在移动发布后发现不匹配要好。

接口也是您在其中建模可选值和失败案例的地方。 如果原生方法不能始终产生电池读数,则 batteryLevel?: number 告诉每个调用者处理 undefined.

下面的图表显示了如何在 Capacitor 中连接类型方法、选项、返回值、桥定义和编译时检查: API

A TypeScript 插件接口示意图,强调了强类型的好处,特别是在移动开发框架中。

核心思想 类型定义从 web 面向的接口流向本机平台逻辑,并在每个调用站点都有编译时检查。

快速查找 API 设计

元素 目的 Example
示例 方法签名 getStatus()
定义可调用的行为 选项类型 { label: string }
Promise 结果 表示异步工作 Promise<DeviceStatus>
结果接口 定义返回的数据 online: boolean

为了更深入的参考,请阅读关于在 TypeScript 中构建 API 的指南 。 两种值得保留的习惯:在客户端中排除机密和签名凭证,测试接口在发布之前针对每个平台的实现移动团队同时处理 JavaScript、native code、设备权限和异步平台服务。 强大的 TypeScript 契约

像一份共享的清单一样在每个边界上工作,使期望在 iOS 或 Android 设备上接收任何 code 之前明确 一位在桌子上放着 __CAPGO_KEEP_0__ 的笔记本电脑旁边喝咖啡的程序员 在这些边界处,工作像一个共享的检查清单,明确了期望,直到任何code在iOS或Android设备上落地。

一位人正在桌子旁边的电脑上编码,显示着code,旁边有一个咖啡杯。

example TypeScript API 示例, 比较一个返回 Promise<DeviceStatus> 的方法与一个返回

未类型化数据的手回。类型化版本告诉编辑器和每个审阅者哪些字段存在。未类型化版本将该发现工作推送到运行时日志、手动测试和最坏情况下、生产事故。

采用信号 TypeScript 已经超出了其前端领域。采用率攀升到35% 的开发者在 2024 年 , 从 2017 年的12% 一百万多名GitHub贡献者 一百万 __CAPGO_KEEP_0__ 贡献者 将其列为他们的主要语言,到 2025 年。深入了解 TypeScript 采用情况的详细情况 如果您想要原始数字。

对于移动组织来说,这条轨迹在实际上有很大的影响。招聘、入职和code审查越来越多地围绕共享类型进行。加入一个Capacitor项目的人可以阅读接口并了解预期的本机行为,而无需跟踪每个实现细节。

类型化API也使发布工作更容易理解。当一个方法要求一个特定的选项对象时,重命名的属性或缺失的字段会在编译时失败,而不是静默地产生一个不完整的本机请求。

强类型会将关键反馈向左移动当修复只需要几分钟,而不是紧急发布修复时。

Capacitor团队的好处

跨平台应用通常暴露一个面向web的API,它位于几个本机实现之上。TypeScript无法证明每个本机细节都行为一致,但它可以确保您的调用在整个应用程序中始终一致。

应用明确类型到:

  • 方法输入包括必填和可选选项
  • Promise结果以便成功数据始终具有可预测的形状
  • 事件和监听器, 因此回调函数处理已知的负载
  • 错误和状态值, 因此fallback路径保持可见

这种结构在集成设备插件或操作服务时会产生回报。它还可以帮助团队审查更新自动化,错误的频道、包标识符或兼容性字段可能会对大量用户造成影响

有关相关模式的更深入探索,请阅读 我们的指南生成类型化API的OpenAPI. 它涵盖了共享定义减少了通常在API文档和应用程序code之间产生的手动漂移

做出商业案例

严格类型化需要一些前期投资,尤其是在旧的JavaScriptcode中包含不一致的数据形状时。随着时间的推移,收益会显现:小的重构、更清晰的所有权和远少的集成惊喜

从风险最大的边界开始:

  1. 定义本地和远程调用响应接口
  2. 输入选项对象和事件负载。
  3. 逐步开启严格编译检查。
  4. 在发布任何更新之前要求类型检查。

对于企业移动团队来说,这个基础使得维护在各个平台、版本和贡献者之间变得可预测。

Capacitor的ScreenOrientationPlugin是一个很好的 TypeScript API example import { registerPlugin } from ‘@__CAPGO_KEEP_0__/core’;

import { registerPlugin } from ‘@capacitor/core’;

export interface OrientationData { type: OrientationType; angle: number; }

export interface LockOptions { orientation: OrientationType; }

export interface ScreenOrientationPlugin { orientation(): Promise

__CAPGO_KEEP_0__的ScreenOrientationPlugin是一个很好的TypeScript__CAPGO_KEEP_0__示例; 锁定(options: LockOptions): Promise; 解锁(): Promise; 添加监听器( eventName: ‘屏幕方向改变’, listenerFunc: (data: OrientationData) =&gt; void, ): Promise&lt;{ remove: () =&gt; Promise}&gt;; } }&gt;; }

(‘ScreenOrientation’);以下是每个签名的快速参考:

—异步读取当前方向

  • orientation() —只接受已知的方向值
  • lock() —恢复正常设备行为
  • unlock() —在方向改变时触发类型化的数据包
  • addListener() 由于每个方法都返回一个Promise,因此您可以使用相同的调用模式对native桥和浏览器实现进行调用。无需分支或特殊情况。

Here’s the quick reference for each signature:

const current = await ScreenOrientation.orientation();

if (current.type.startsWith('landscape')) { console.logAngle: ${current.angle}); }

await ScreenOrientation.lock({ orientation: '横屏', });

输入错误的值,如 landscape-main 并且编译时即会失败。这种情况下你需要秒级修复,而不是在设备日志中追踪平台相关的运行时错误。

正确传递监听函数参数

监听函数应与普通方法一样严谨。避免 any 因为这会隐藏事件载荷和返回值之间的区别。 orientation() returns.

const subscription = await ScreenOrientation.addListener( ‘screenOrientationChange’, handleChange, );

await subscription.remove();

await subscription.remove();

只在两种原生实现都保证相同字段时共享一个类型。如果一个平台省略了 OrientationData 标记它为可选并要求调用者处理 angle设计选择 undefined.

更安全的模式 输入
命名选项接口 结果
明确的 Promise 类型 事件
字面事件名称 清理
Cleanup 返回可移除的订阅

接口是桥接合约,而不是原生实现。 保持小巧、可预测和可测试。

对于平台行为、权限和安装步骤,请阅读 Capacitor 屏幕方向插件指南。最后一个值得采纳的习惯是在严格的 TypeScript 设置下测试有效调用和被拒绝的调用。这种结合在包装移动应用之前捕捉错误的方法名称、缺失的字段和不兼容的监听器负载。

Capgo 给了 Capacitor 团队推送 JavaScript、CSS、配置和资产修复的方式,而不必等待应用商店审查。关键在于将其更新管道视为任何其他类型的 API 边界,例如通道、回滚规则、兼容性检查和回滚决策都保持明确,直到包裹到达用户设备之前。

一位手持智能手机的人,展示了横屏和竖屏屏幕方向模式的差异。

定义更新契约

首先通过将值固定下来来确定您的自动化接受什么。字面联合可以防止您意外部署到错误的通道,而接口可以使包裹和其所需的原生版本之间的关系自我文档化。

类型 Channel = ‘beta’ | ‘staging’ | ‘production’;

interface UpdateRequest { channel: Channel; bundleVersion: string; minNativeVersion: string; rolloutPercent: number; signed: boolean; }

interface UpdateResult { accepted: boolean; appliedOnNextLaunch: boolean; rollbackEnabled: boolean; }

A直接 TypeScript API 示例 验证请求之前将其传递给 Capgo 客户端:

async function publishUpdate( request: UpdateRequest, ): Promise { if (!request.signed || request.rolloutPercent &lt; 0 || request.rolloutPercent &gt; 100) { throw new Error(‘不安全的更新请求’); }

return capgo.publish(request);

在 Capgo SDK 版本之间,客户端方法名称会发生变化,因此将其包装在自己的接口后。这种隔离在升级时会带来收益,并且避免了代码库中出现供应商特定的细节。

Guard Channels 和 Compatibility

选择频道不应随意。生产发布需要比实验性beta版本更严格的检查,尤其是当web包调用本地能力时,这些能力在早期应用版本中并不存在。

function 可以部署(\nrequest: UpdateRequest,\ninstalledNativeVersion: string,\n): boolean {\nreturn request.signed &amp;&amp;\ninstalledNativeVersion &gt;= request.minNativeVersion;\n}

不要使用普通字符串来比较版本。引入一个合适的语义版本库 1.10.0 根据类型 1.9.0在任何内容传递到频道之前,需要检查以下事项:

  1. 确认捆绑包已签名。
  2. 确认目标频道与意图匹配。
  3. 比较原生和捆绑包兼容性范围。
  4. 首先发布给受限的受众。
  5. 监控失败信号并保持回滚准备就绪。

一个类型化的更新管道将发布策略转化为code,供审查员和CI系统检查。

Capgo的差异性传递和频道控制可以很好地融入该模式,并且其设备级观察性使团队可以在事后追踪采用或失败信号。有关事件仪表板的另一方面,请参阅 this guide to custom event tracking with Capgo.

签名密钥和管理员凭据应放在服务器或CI系统中,而不是在已发布的应用程序中。下次启动时应用更新,测试回滚并拒绝捆绑包,使用类型化的结果记录每个决策。这种结合方式可以保持快速传递与有条不紊的移动发布控制兼容。

类型化的监听器使异步API更容易信任。无论回调跟踪屏幕方向还是Capgo更新事件,它都应在每个平台上接收相同的payload形状——并且编译器应该是执行这一点的。

interface UpdateEvent { version: string; channel: 'beta' | 'production'; available: boolean; }

类型 = (payload: T) =&gt; void;

interface UpdateService { 添加监听器( 事件:‘updateAvailable’, 回调:Listener }Promise{ remove: () => Promise} }&gt;;\nremoveAllListeners(): Promise; }

本示例 TypeScript API 示例 将事件名称固定到字面值,并将回调函数与类型化的数据绑定。您的编辑器可以自动完成提示,并且编译器会拒绝任何期望的数据不相关的回调函数。这种设置虽然很少,但每次 __CAPGO_KEEP_0__ 变化时都会带来收益。 version for free, and the compiler rejects any callback that expects unrelated data. It’s a small amount of setup, and it pays off every time the API changes.

安全注册监听器

__CAPGO_KEEP_0__

Inside a component, keep the subscription handle around so cleanup stays explicit. The same pattern drops into Angular lifecycle hooks, React effects, and Vue mount hooks without changes.

let orientationHandle: { remove: () =&gt; Promise} } | undefined;

async function stop() { await orientationHandle?.remove(); orientationHandle = undefined; }

async function stop() { await orientationHandle?.remove(); orientationHandle = undefined; }

Each framework gives you a hook for this:

Angular

  • — 触发清理 React ngOnDestroy
  • React Vue useEffect
  • context — 取消订阅 onBeforeUnmount

每次 addListener 每个调用都应有匹配的清除路径。

选择正确的清除方法

当一个组件拥有一个订阅时,返回的句柄是正确的调用。 removeAllListeners() 当一个服务持有多个监听器并且正在完全重置时,

async function resetUpdates(service: UpdateService) { await service.removeAllListeners(); }

不要从共享组件中触发广泛方法,而其他屏幕仍然依赖于服务。当拥有权是本地的,坚持使用单独的 remove() 情况

推荐的行动 一个组件订阅
当一个服务持有多个监听器并且正在完全重置时, 呼叫 handle.remove()
服务关闭 呼叫 removeAllListeners()
重复注册 守卫初始化
未知载荷 在使用之前验证

对于Capgo通知,保持更新载荷与设备事件分开。然后在它们自己的测试注册、传递和清理——该Capgo自定义事件跟踪指南 Capgo 个性化事件跟踪指南 有更多关于整合方面的内容。

一名专业的软件开发人员正在Capacitor上工作,使用双显示器,戴着耳机。

code

一个良好的构建 TypeScript API 示例 以描述意图的名称开始。 使用动词作为方法,名词作为接口,坚持一致的后缀,如 Options, Result, 和 Event. 清晰的名称可以减少入门时间,因为开发人员可以在不打开实现的情况下理解契约。

保持公共接口小。 通过专注的方法暴露能力,而不是将松散相关的操作dump到单个对象上。

  • getStatus() 读取状态。
  • updateConfig(options) 更改配置。
  • addListener(event, callback) 订阅更改。

Type Inputs and Outputs Precisely

当参数可能增长时,使用命名选项接口:

interface PublishOptions { channel: ‘beta’ | ‘production’; rolloutPercent: number; }

interface PublishResult { 版本: string; 接受: boolean; }

async function publish( options: PublishOptions, ): Promise {\nreturn client.publish(options);\n}

泛型在这种情况下得到了合理的应用:当一个API需要处理不同类型的数据时,需要保留它们的具体类型

ApiResponse {\ndata: T;\nrequestId: string;\n}

异步函数 request(path: string): Promise&lt;ApiResponse&gt;&gt; {\nreturn fetchJson&lt;ApiResponse>&gt;(路径);

不要为了显示灵活性而添加泛型。泛型应该表达输入和输出之间的真实关系 —— 否则,一个具体的接口更容易阅读和维护

使无效状态难以表示,尤其是在原生、网络和更新边界处。

在契约旁边记录行为。涵盖权限、单位、被拒绝的承诺、可选字段以及方法是否立即应用还是在下一次启动时应用。内联注释应该解释决策,而不是重复方法名称。

组织Code的变更

将类型、客户端逻辑、平台适配器和测试分离到可预测的文件中。从一个入口点导出公共类型,并将实现细节保密。

关注点 推荐位置
公共接口 types.ts
API方法 client.ts
原生适配器 platform/
兼容性测试 tests/

对于破坏插件更改,引入一个新的主要接口或兼容性层,暂时保留过时的方法,并记录迁移步骤。 了解更多关于API版本控制策略 在更改消费者之前。

在CI中运行严格类型检查和契约测试。对于Capgo工作流程,验证通道值、原生兼容性、签名包和回滚行为作为类型化发布规则 — 这样可以在团队、平台和集成增长时保持快速更新的控制。

如何类型化动态原生结果?

不要让 any 泄漏到你的code中,当原生方法返回不可预测的数据时。相反,明确你可以依赖的字段,标记真正的可选值为,并在边界处对不确定的输入进行清洁处理,以便下游任何东西都不会接触它。 ?interface NativeResult { success: boolean; value?: string; }

async function readValue(): Promise

async function readValue(): Promise 这种方法会让你的调用者安全,同时在类型本身中明确了不确定性。要了解此接口模式的更广泛视角,请参阅

在TypeScript中构建API 如何让监听器避免未处理的拒绝?.

如何让监听器避免未处理的拒绝?

异步回调需要以防御性设计。 在监听器内部捕获失败而不是依赖事件系统默默地吞没被拒绝的承诺。

const handleUpdate = (event: UpdateEvent): void => { void applyUpdate(event).catch((error: unknown) => { console.error('Update failed', error); }); };

保持订阅引用并在组件卸载时移除它。这样可以防止重复回调和过时的状态更新——监听器生命周期部分详细介绍了这一点。

每个异步监听器都需要一个错误路径和一个清理路径。

如何保护Capgo更新

签名密钥和管理凭证始终保留在您的服务器或CI系统上。期限。客户端应只接收已签名的捆绑包,并使用类型化的结果显示状态——绝不用于创建签名。

在发布之前,设置单独的频道联盟,运行兼容性检查,配置发布限制,并规划回滚路径。 Capgo 处理签名交付、渠道控制、下一版应用和回滚保护的Capacitor和 Electron 应用。他们的文档展示了如何通过类型化的发布流程来优化更新管道。

实时更新Capacitor应用

当 web 层 bug 实时更新时,通过 Capgo 发送修复,而不是等待几天的 app 商店审批。用户在后台接收更新,而原生变化仍在正常审批路径中。

来自 Martin 的人性化支持

立即开始

最新博客文章

Capgo 给您创建真正专业的移动应用所需的最佳见解。