为什么下面的代码没有经过类型检查(TypeScript 5.5.4):
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
是"success" | "invalid_or_expired_token"
。当 TypeScript 在进行控制流分析时,它能够看到 来自type
,x.type
那么 TS 足够聪明,能够猜测如果x.type
是"success"
,那么x
具有属性token_info
。B)
在这种情况下,
type
也是"success" | "invalid_or_expired_token"
。当 TypeScript 进行控制流分析时,它无法看到type
来自x.type
。您的注释{type: ValidationResult$Type}
优先于从 推断x
,那么 TS 无法将这些点连接起来并猜测如果type
是"success"
,则x
具有 属性token_info
。这个故事的寓意是,您应尽可能避免添加手动类型注释。