Пара вещей:
Во-первых,
Array<A | B>
(A | B)[]
все идентичны.
Во-вторых, причина, по которой A
назначается обоим, заключается в том, что все свойстваA также находятся в B.
В-третьих, не изменяйте состояние.Переназначение этого недостаточно.
> const x = {}
undefined
> const y = x
undefined
> y.a = 1
1
> x
{ a: 1 }
Вы можете разделиться на новый объект: let newState = { ...state }
- этого вполне достаточно.
Хорошо.Вы не можете присвоить значение типа A | B
чему-то, что имеет тип B
.Вы использовали что-то другое (type
), чтобы сигнализировать о другом значении, но TS не может знать об этом, пока вы не скажете это.Есть несколько разных способов сделать это.
Во-первых, утверждать:
newState.b = action.data as B[];
Это фактически говорит TS о том, что он должен выключиться.Чаще всего это нормально ... Если вы делаете что-то действительно сомнительное, TS заставит вас сначала заявить unknown
.Это не тот случай, здесь.
, но есть и лучшие способы сделать это.
Немного лучше: наберите охрану
Это требует рефакторинга коммутатора:
function isA(x: any): x is IAction<Array<A>> {
return x.type === '1'
}
function isB(x: any): x is IAction<Array<B>> {
return x.type === '2'
}
...
if (isA(action)) {
newState.a = action.data;
} else if (isB(action)) {
newState.b = action.data;
}
( note : я не могу заставить это работать ... код правильный, я просто набираю never
для действия после первой проверки - не уверен, что здесь происходит)
Наконец, пусть TypeScript выполнит для вас разрешение с помощью duck-typing .
Это означает, что если у вас есть свойство в объекте, которое коррелирует с типомTS может автоматически подбирать типы, если это свойство достаточно уникально.