Iot 设备编号生成

🔌 TypeScript 魔法:一行代码生成从 1 开始编号的 IoT 设备字典

在物联网(IoT)项目中,我们经常需要为大量设备生成严格类型化的数据模型。今天分享一个超实用的 TypeScript 技巧:利用模板字面量 + 递归元组 在编译期自动生成「IOT1、IOT2 ... IOTN」的键值对象,并保证从 1 开始编号!


🎯 场景痛点

假设你要给 100 个温度传感器建一个字典,键名必须是 T1 ~ T100,值是 number

ts 复制代码
const data = {
  T1: 23.7,
  T2: 24.1,
  // ... 手写 100 个键?😱
};

手写不仅累,还容易错。我们希望:

  1. 编译期就能校验键名范围
  2. 从 1 开始而不是 0
  3. 一行类型搞定,拒绝运行时魔法

🧙‍♂️ 解法:类型体操三步走

Step 1: 构造指定长度的元组

ts 复制代码
type BuildTuple<L extends number, T extends any[] = []> =
  T['length'] extends L 
  ? T 
  : BuildTuple<L, [...T, any]>;
  • BuildTuple<3>[any, any, any]

Step 2: 把元组索引变成字符串并 +1

ts 复制代码
type TupleIndices<T extends readonly any[]> = keyof T & `${number}`;

type AddOne<S extends string> =
  S extends `${infer N extends number}`
    ? `${[...BuildTuple<N>, any]['length']}`   // N + 1 并转回字符串
    : never;

Step 3: 生成最终对象类型

TypeScript

ts 复制代码
type CreateIotData<
  Prefix extends string,
  ValueType,
  Count extends number
> = {
  [K in TupleIndices<BuildTuple<Count>> as `${Prefix}${AddOne<K>}`]: ValueType;
};

🚀 实战演示

1. 定义 5 个智能灯泡的亮度

TypeScript

ts 复制代码
type Bulbs = CreateIotData<'Light', number, 5>;
// 等价于:
// type Bulbs = {
//   Light1: number;
//   Light2: number;
//   Light3: number;
//   Light4: number;
//   Light5: number;
// }

2. 100 个温度传感器

TypeScript

ts 复制代码
type Sensors = CreateIotData<'T', number, 100>;
// T1 ~ T100

3. 自动补全 & 类型检查

在 VS Code 中键入:

TypeScript

ts 复制代码
const data: Bulbs = {
  Light1: 80,
  Light2: 90,
  // ❌ 直接提示缺少 Light3/4/5
}

🧪 更多玩法

表格

需求示例 用法
十六进制地址 CreateIotData<'0x', string, 16>0x1 ~ 0x10
布尔开关 CreateIotData<'SW', boolean, 8>
动态前缀 CreateIotData<device_${string}, number, 50>

📌 总结

  • 零运行时开销:全部是编译期类型
  • 1 开始编号 :告别 device0
  • 可维护 :改 Count 即可重新生成

把这段类型丢进你的 IoT 工具库,下次评审再也不用解释"为什么从 0 开始"了!

📌 整体代码

ts 复制代码
type BuildTuple<L extends number, T extends any[] = []> =
  T['length'] extends L
  ? T
  : BuildTuple<L, [...T, any]>;

type TupleIndices<T extends readonly any[]> = keyof T & `${number}`;

type AddOne<S extends string> = `${S}` extends `${infer N extends number}`
  ? [...BuildTuple<N>, any]['length']
  : never;

type CreateIotData<
  Prefix extends string,
  ValueType,
  Count extends number
> = {
    [K in TupleIndices<BuildTuple<Count>> as `${Prefix}${AddOne<K>}`]: ValueType;
  };

相关推荐
梦曦i15 小时前
uni-router新推useUniEventChannel,彻底解决页面通信难题
前端·uni-app
柯克七七15 小时前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript
yuanlaile15 小时前
前端转 Flutter 自学完整规划,避开跨栈思维转换误区
前端·flutter·flutter跨平台开发
CN_HW15 小时前
Nginx 流量镜像配置文档-双轨国产化
服务器·前端·网络
JNX_SEMI16 小时前
ATR2652 GNSS双频LNA:0.75dB噪声系数与22dB高增益设计
前端·单片机·嵌入式硬件·物联网·硬件工程
拾年27516 小时前
Node.js 异步进化论:从 path 路径拼接到 fs 文件读取,我终于理解了回调地狱的救赎之路
前端·node.js
花颜yyds16 小时前
React Konva 开发基础速查手册
前端
小粉粉hhh16 小时前
Node.js(五)——编写接口
前端·javascript·node.js
MegatronKing17 小时前
AI时代我们要如何玩抓包测试
前端·后端·测试
uhakadotcom17 小时前
Scrapy-Redis 里面提供哪些即开即用的功能能力模块
前端·面试·github