为何TypeScript中指定类型后switch语句类型收窄失效
为什么两段相似的TypeScript代码,一段无法通过类型检查,另一段可以?
无法通过类型检查的代码
type ValidationResult$Type = 'success' | 'invalid_or_expired_token' export type ValidationResult = { type: 'success' token_info: object } | { type: 'invalid_or_expired_token' }; const x: ValidationResult = undefined as unknown as ValidationResult; const {type}: {type: ValidationResult$Type} = x; switch (type) { case 'success': const {token_info} = x; break; case 'invalid_or_expired_token': break; }
可以通过类型检查的简化代码
// type ValidationResult$Type = 'success' | 'invalid_or_expired_token' export type ValidationResult = { type: 'success' token_info: object } | { type: 'invalid_or_expired_token' }; const x: ValidationResult = undefined as unknown as ValidationResult; // const {type}: {type: ValidationResult$Type} = x; const {type} = x; switch (type) { case 'success': const {token_info} = x; break; case 'invalid_or_expired_token': break; }
问题原因
核心在于联合类型判别式的关联关系被破坏:
简化版代码中,
type直接从联合类型ValidationResult解构而来,TypeScript 会自动维护type和原变量x的关联。当switch匹配case 'success'时,TypeScript 能精准将x的类型收窄到包含token_info的成员,因此解构token_info不会报错。报错的代码里,手动给解构出的
type指定了独立类型{type: ValidationResult$Type},这切断了type和x的关联。此时 TypeScript 无法通过type的值来收窄x的类型——它无法确认当前的type和x的type是同一个值,所以在case 'success'分支中,x仍被视为完整的联合类型,TypeScript 不确定它是否包含token_info,因此抛出类型错误。
直白来说:手动指定类型破坏了 TypeScript 联合类型的类型收窄逻辑,导致判别式失去作用。
内容的提问来源于stack exchange,提问作者Marcus Junius Brutus
相关产品推荐
相关产品推荐

