You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用品牌类型键与对象展开时TypeScript未检测类型错误

TypeScript品牌化字符串作为对象键时,对象展开导致类型检查失效的问题

这是TypeScript的已知编译器bug,既不是你的理解错误,也不属于预期行为。

问题复现

你的最小复现代码已经准确命中了这个bug场景:

type SpecialKey = string & {__SpecialKey: true};

type SpecialKeysToStrings = {
  [key: SpecialKey]: string;
}

// 正常工作
const obj1: SpecialKeysToStrings = {
  ['myKey' as SpecialKey]: "string",
};

// 值非string,编译器正确捕获错误
const obj2: SpecialKeysToStrings = {
  ['myKey' as SpecialKey]: 100,
};

// 值非string,编译器未检测到错误(bug触发点)
const obj3: SpecialKeysToStrings = {
  ...{},
  ['myKey' as SpecialKey]: 100,
}

原因分析

品牌化字符串是TypeScript中模拟名义类型的常用手段,但TypeScript的对象字面量类型合并逻辑在处理「展开语法 + 品牌化键」的组合时存在漏洞:

  • 当对象字面量中存在展开操作时,编译器会先处理展开的对象类型,再合并后续属性
  • 此时品牌化键的特殊约束会被降级为普通string类型,导致后续属性的值类型检查完全绕过了SpecialKeysToStrings中string值的要求

临时解决方案

可以通过以下方式规避这个bug:

  • 直接创建不含展开语法的对象字面量(如obj1、obj2的写法)
  • 使用Object.assign替代展开语法,保留类型检查:
    const obj3: SpecialKeysToStrings = Object.assign({}, {
      ['myKey' as SpecialKey]: 100 // 这里会正确触发类型错误
    });
    

内容的提问来源于stack exchange,提问作者joshuahhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 16:55:58