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

TypeScript中User | Record<string, never>联合类型键访问异常问题

解决方案

你的问题出在Record<string, never>的类型特性上:它通过索引签名声明了所有字符串键对应的值类型都是never,但TypeScript处理联合类型时,never会被其他类型“吸收”。比如User | Record<string, never>中,访问role时,TypeScript会认为User的role是有效类型,而Record<string, never>的role是never,最终联合类型会被简化为User['role'](即string),所以不会触发报错。

要实现你想要的效果——空对象类型访问role时直接报错,需要让空对象类型明确不包含role属性,且与User类型不兼容。这里有两种可靠的实现方式:

方式一:用唯一符号标记空对象

通过添加一个唯一的符号属性,让空对象类型与User彻底区分开,同时允许空对象{}赋值:

interface User {
  role: string;
}

// 定义唯一符号作为空对象的标记
const emptyObjMarker = Symbol('empty-object');
// 空对象类型:可选的符号属性,确保与User不兼容
type EmptyObject = { [emptyObjMarker]?: never };
// 最终的联合类型
type StateUser = User | EmptyObject;

// 测试场景
const validUser: StateUser = { role: 'admin' };
validUser.role; // 正常,类型为string

const emptyUser: StateUser = {};
emptyUser.role; // 触发报错:Property 'role' does not exist on type 'EmptyObject'.

方式二:明确禁止User的所有属性

通过映射类型定义一个不能拥有User任何属性的空对象类型,确保空对象{}符合要求,同时访问role会报错:

interface User {
  role: string;
}

// 定义空对象类型:User的所有属性都是可选的never类型(即不能存在这些属性)
type EmptyObject = { [K in keyof User]?: never };
type StateUser = User | EmptyObject;

// 测试场景
const validUser: StateUser = { role: 'admin' };
validUser.role; // 正常

const emptyUser: StateUser = {};
emptyUser.role; // 触发报错:Property 'role' does not exist on type 'EmptyObject'.

这两种方式都能让TypeScript正确识别联合类型的差异,在访问role时,若未通过类型收窄确认是User类型,就会触发你期望的属性不存在错误。

内容的提问来源于stack exchange,提问作者Thiago Pereira Maia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:17:01