在typescript的条件块中使用联合类型

3phpmpom  于 2023-02-13  发布在  TypeScript
关注(0)|答案(1)|浏览(149)

我正在学习typescript,并尝试使用reactjs强类型useReducer。这是reducer的逻辑,但typescript对我大喊,属性incStep不存在于Act上,因为它不存在于Decrement上。

type Increment = {
    type: string,
    incStep: number
}

type Decrement = {
    type: string,
    decStep: number
}

type State = {
    count: number
}

type Actions = Increment | Decrement

const reducer = (state: State, action: Actions) : State =>  {

    if(action.type == 'Inc') {
        return {count: state.count + action.incStep }
    } else if(action.type == 'Dec') {
        return {count: state.count - action.decStep}
    }

    return state
}

获取以下错误:类型"Act"上不存在属性"incStep"。类型"Dec"上不存在属性"incStep"。
现在我认为联合类型是指全部或其中之一。
例如

const action : Actions = {
  type: 'inc',
  incStep: 1,
  decStep: 2'
}

// or

const action : Actions = {
  type: 'inc',
  incStep: 1,
}

// or 

const action : Actions = {
  type: 'dec',
  decStep: 1,
}

我也知道switch语句在这里很好用,但是我使用if-else是因为操作类型的数量只有两个。
我知道如果我使用字符串类型'inc'|"dec',那我就没问题了。
有人能解释一下我做错了什么吗?

wn9m85ua

wn9m85ua1#

我认为在这里使用discrimination types是理想的。
您可以在此处了解有关discrimination types的更多信息

type Increment = {
  type: "Inc"; // this field is the differentiator
  incStep: number;
};

type Decrement = {
  type: "Dec"; // this field is the differentiator
  decStep: number;
};

type State = {
  count: number;
};

type Actions = Increment | Decrement;

const reducer = (state: State, action: Actions): State => {
  switch (action.type) {
    case "Inc":
      return { count: state.count + action.incStep };
    case "Dec":
      return { count: state.count - action.decStep };
    default:
      return state;
  }
};

使用switch case是编写此类代码的一种更好、更简洁的方法,因为它提供了更好的可读性,并遵循DRY原则。

相关问题