我有以下example:
interface LoadingState {
state: 'loading';
}
interface DoneState {
state: 'done';
data: any;
}
const test = (params: LoadingState | DoneState) => {
const { state } = params;
if ( state === 'loading') {
return console.log('LoadingState');
}
const { data } = params
}
该代码的最后一行是抛出一个错误:Property 'data' does not exist on type 'LoadingState | DoneState'.
我目前用一个明确的类型转换来规避这个问题:
const { data } = this.state as DoneState<T>;
问题是,TS知道状态的唯一有效选项是“完成”,这意味着必须定义数据。我错过了什么吗?我应该以不同方式定义我的界面吗?
编辑
我的问题甚至不是我问的问题。抱歉!!原来我的问题比我想象的要复杂一点!我有像this这样的东西:
interface LoadingState {
state: 'init' | 'loading';
}
interface DoneState {
state: 'done';
data: any;
}
const test = (params: LoadingState | DoneState) => {
const {state} = params;
if ( state === 'loading' || state === 'init') {
return console.log('LoadingState');
}
const {data} = params;
}
为了解决这个问题,我不仅要避免对params进行解构,而且还必须为InitState
添加一个新接口来拆分state: 'init' | 'loading';
定义。这是工作的result。
问题是,TS知道状态的唯一有效选项是“完成”
是的,但它没有使state
变量的类型连接到params
来自的state
对象的类型。如果您在params.state
内使用if
检查它是否按预期工作:
const test = (params: LoadingState | DoneState) => {
if ( params.state === 'loading') {
return console.log('LoadingState');
}
const { data } = params
}
打字稿实际上并不知道你正在测试哪种类型是params里面的if条件。你可以明确告诉编译器你正在使用一个名为type guard的东西:ts-playground