Yak*_*ych 8 discriminated-union typescript
我试图使用Typescript Discriminated Union来模拟异步加载数据时的一个相当常见的场景:
type LoadingState = { isLoading: true; }
type SuccessState = { isLoading: false; isSuccess: true; }
type ErrorState = { isLoading: false; isSuccess: false; errorMessage: string; }
type State = LoadingState | SuccessState | ErrorState;
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这应该根据类型定义限制允许的值组合.但是,类型系统很乐意接受以下组合:
const testState: State = {
isLoading: true,
isSuccess: true,
errorMessage: "Error!"
}
Run Code Online (Sandbox Code Playgroud)
我希望这里有一个错误.有什么我缺少或在某种程度上滥用类型定义?
Tit*_*mir 18
这是超额财产检查对工会的影响方式的问题.如果将对象文字分配给联合类型的变量,则如果属性存在于任何联合成员上,则不会将该属性标记为多余.如果我们不认为多余的属性是一个错误(除了对象文字它们不被认为是错误),你指定的对象文字可以是LoadingState(一个实例isLoading设置true为强制的实例和一些多余的属性) ).
为了解决这种不受欢迎的行为,我们可以添加属性LoadingState以使您的对象文字不兼容LoadingState
type LoadingState = { isLoading: true; isSuccess?: never }
type SuccessState = { isLoading: false; isSuccess: true; }
type ErrorState = { isLoading: false; isSuccess: false; errorMessage: string; }
type State = LoadingState | SuccessState | ErrorState;
const testState: State = { // error
isLoading: true,
isSuccess: true,
errorMessage: "Error!"
}
Run Code Online (Sandbox Code Playgroud)
我们甚至可以创建一种确保添加此类成员的类型
type LoadingState = { isLoading: true; }
type SuccessState = { isLoading: false; isSuccess: true; }
type ErrorState = { isLoading: false; isSuccess: false; errorMessage: string; }
type UnionKeys<T> = T extends any ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
type State = StrictUnion< LoadingState | SuccessState | ErrorState>
const testState: State = { // error
isLoading: true,
isSuccess: true,
errorMessage: "Error!"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
471 次 |
| 最近记录: |