交叉路口"...&..."被简化为"从不",因为财产"..."在某些成分中具有冲突的类型



我有两个类定义如下:

class FirstClass {
values: FirstValuesType = {} as FirstValuesType;
setValues(values: FirstValuesType): void {
this.values = { ...values };
}
}
class SecondClass {
values: SecondValuesType = {} as SecondValuesType;
setValues(values: SecondValuesType): void {
this.values = { ...values };
}
}
interface CommonValuesType {
id: number;
property1: string;
property2: string;
}
enum FirstReasonEnum {
A, B, C
}
enum SecondReasonEnum {
X, Y, Z
}
interface FirstValuesType extends CommonValuesType {
reason: FirstReasonEnum;
}
interface SecondValuesType extends CommonValuesType {
reason: SecondReasonEnum;
}

然后我定义了一个常量,它可以是以下类之一:

const model: FirstClass | SecondClass;

当我这样调用setValues:

model.setValues(newValues);

我得到以下错误:

Argument of type '{ id: number; property1: string; property2: string; reason: FirstReasonEnum; }' is not assignable to parameter of type 'never'.
The intersection 'FirstValuesType & SecondValuesType' was reduced to 'never' because property 'reason' has conflicting types in some constituents.(2345)

如何解决这个问题?

编辑:

这是到操场的链接:

https://www.typescriptlang.org/play?ts=4.3.5代码/FDDGBsEMGdoAgGIEsBO0AuBhKs4G9g44A3ScAVwFNoAuRVDANTKugBUBPAB0rgF58AXzgx6adMwrVOPANwgi0ShJbUAFKSm0xTVe26UAlHWIB7JABN8hInHQALJNAB0m1v3xxn3t9TiD5IkFgYLAceABlSlBTADsLbBh4AiJfbSiY + MlWGV4BPGFRDLiLbOkDeRslFS0NPTpirL1c4xJzKxTbBydXPQ88Lx8 + gJtg0KRY9EoUADNIUF5MUwBbZbiy-R5rWzhLOljyZYAjacDbLhRTHhR0DgBGOgwUCYBzM6ILq + nbgCZH9GesTeIRAlAOyx06AASpQYHEAKLg7a2ACCABo4AAhDGYEHAMGHOCNCwwuGxRGEzpEAAaGIAmhiAFp4iZTWbzXjIcQbXJwSgADym8XgS1W62aBmRKFh0DidC5GFJsvJ4Mq40m0zmCyJ0 rkpmlaqffhfkzwsx1w060rjdv18svcnveigstgafkoilcj0qdyjkh0goapprcyucdyhhycjwaa + OsyCXChmRREyGDgofDkfEXvg8eJeY8IdMYfAlR26fQcFilAA7ht + jYdns7mjm + dLtdbg84AByT7d + 599 s7d5d74cp79wetn4jjtea3knokmwow7oded4jjzol8poaobns1ht6qzvfwgqraa

您的代码假设modelFirstClass的一个实例,但是类型表明它可能是FirstClass的一个实例,也可能是SecondClass的一个实例。由于不清楚它是哪个,但setValues需要知道,TypeScript会为你突出显示你传递的参数是无效的(或者我应该说可能不是是有效的)。它不可能是有效的,因为它不能同时是FirstValuesTypeaSecondValuesType(这是FirstValuesType & SecondValuesType的意思),因为reason的类型不同。

解决这个问题的最小更改方法是测试你必须看到它是否是FirstClass实例,你可以这样做,因为你已经使用了一个类(而不仅仅是一个接口)。所以这个修复了它:

if (model instanceof FirstClass) {
model.setValues(newValues);
} else {
// ...code here to do something with the `SecondClass` `model`
}

操场例子


也就是说,您可能需要重新考虑整个结构,但这实际上取决于具体情况,这看起来像是一个简化的示例(为了提问的目的,进行了适当的简化)。FirstClassSecondClass,以及FirstValuesTypeSecondValuesType,除了reason使用的enum类型外,其他都是相同的。您可以考虑在单个TheClassValuesType上使用泛型类型参数。但这不会改变一个基本问题,即init中的代码假设模型是一回事,而它可能是两件事中的一件。


旁注:init代码的这一部分似乎有点可疑:

const model: TheClass<EnumType> = _model;
// ...
model.setValues(newValues);

model常量和_model形参指向同一个对象,所以不创建不必要的额外标识符,直接使用_model会更直接:

_model.setValues(newValues);

无论哪种方式,都是在修改传入的对象。(如果要复制对象,则需要执行复制操作。)

最新更新