gpt4 book ai didi

typescript - 具有联合类型的泛型抛出不可分配错误

转载 作者:行者123 更新时间:2023-12-03 21:19:07 26 4
gpt4 key购买 nike

我有一个 reducer ,它有一个 Action 创建器,它可以是两个不同类型对象的数组,每个对象都有自己的接口(interface)。但是,我收到此错误

Type '(A | B)[]' is not assignable to type 'B[]'.
Type 'A | B' is not assignable to type 'B'.
Property 'productionId' is missing in type 'A' but required in type 'B'

我怀疑这个错误是由于两个接口(interface)具有相似的值,除了 B 比 A 有一个额外的值?

这里是 typescript playground

这是完整的可重现代码
interface A {
id: number;
name: string;
}

interface B {
id: number;
productionId: number;
name: string;
}

interface IAction<Data> {
type: string;
data: Data;
}

interface ISelectionOptionsReducerState {
a: A[];
b: B[];
}

let initialState: ISelectionOptionsReducerState = {
a: [],
b: []
};

type TAction = IAction<Array<A | B>>;
type TAction = IAction<A[] | B[]>; <= this didn't work either

type TReducer = (
state: ISelectionOptionsReducerState,
action: TAction
) => ISelectionOptionsReducerState;

const selectionOptionsReducer: TReducer = (
state: ISelectionOptionsReducerState = initialState,
action: TAction
): ISelectionOptionsReducerState => {
Object.freeze(state);

let newState: ISelectionOptionsReducerState = state;

switch (action.type) {
case '1':
newState.a = action.data;
break;
case '2':
newState.b = action.data; <= error happen here
break;
default:
return state;
}

return newState;
};

最佳答案

几件事:

第一的,

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第一的。不过,这里并非如此。

但有更好的方法来做到这一点。

稍微好一点:类型 guard

这需要重构开关:
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;
}

( 注意 :我实际上无法让它工作......代码是正确的,我只是在第一次检查后输入 never 以执行操作 - 不确定这里发生了什么)

最后, let TypeScript do the resolution for you via duck-typing .

tl; dr 是,如果您在对象中具有与类型相关的属性,则如果该属性足够独特,TS 可以自动选择类型。

关于typescript - 具有联合类型的泛型抛出不可分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56532498/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com