TypeScript中如何避免解构session后误用原session变量
禁止解构后误用原入参变量的实现方法
delete session 报错是符合预期的:JS严格模式下本身就不允许对函数参数、var/let/const声明的标识符直接调用delete,这是语法层面的限制,和TypeScript无关,该写法本身就无法在严格模式下运行。
可以通过以下几种方式实现约束,从编译阶段就阻断对原session变量的误用:
- 入参阶段直接解构,从根源消除原变量
最彻底的方案是直接在函数参数定义时完成解构,整个函数作用域内根本不会存在完整的session标识符,后续代码自然不可能访问到原变量,从根源避免误用:// 入参直接解构,函数体内不存在session变量 public async createOrUpdateOfflineSession( { id, ...sessionWithNoId }: SessionInterface, store: Store ) { const existingSession = await this.prisma.shopifyOfflineStoreSession.findUnique({ // 这里如果写session.shop会直接报"找不到名称session"的编译错误 where: { shop: sessionWithNoId.shop }, }); if (existingSession) { await this.prisma.shopifyOfflineStoreSession.update({ where: { shop: sessionWithNoId.shop }, data: { ...sessionWithNoId, sessionId: id }, }); } else { await this.prisma.shopifyOfflineStoreSession.create({ data: { ...sessionWithNoId, sessionId: id, store: { connect: { id: store.id } }, }, }); } } - 解构后立刻将原变量标记为
never类型
如果需要先对完整的session做前置校验、不能直接在入参阶段解构,可以在解构完成的下一行重新声明同名session变量为never类型,后续所有访问session的代码都会触发TS类型报错,在编译阶段就拦截误用,且不会产生额外运行时开销:public async createOrUpdateOfflineSession(session: SessionInterface, store: Store) { // 前置校验逻辑(如果需要) if (!session.shop) throw new Error('invalid session'); const { id, ...sessionWithNoId } = session; // 阻断原session的后续使用,TS编译后会擦除所有类型标注,不影响运行 const session: never = undefined as never; // 后续代码只要访问session就会报"类型never上不存在xxx属性"的错误 const existingSession = await this.prisma.shopifyOfflineStoreSession.findUnique({ where: { shop: sessionWithNoId.shop }, }); // 剩余逻辑同上面的示例 } - 静态检查规则强制约束
团队项目中可以搭配ESLint做强制校验:开启no-unused-vars规则检测解构后未再使用的原变量,也可以根据团队编码规范自定义规则,检测到解构赋值后后续代码访问原对象时直接抛出lint错误,在代码提交环节就拦截问题。
注:你提供的示例代码存在两处语法问题:一是
update方法的配置对象中重复写了两次data键,二是if代码块缺少闭合的花括号,实际运行前需要修正。
内容的提问来源于stack exchange,提问作者Gezim
相关产品推荐
相关产品推荐

