简体   繁体   English

交集 '... &...' 被缩减为 'never' 因为属性 '...' 在某些成分中具有冲突的类型

[英]The intersection '... & ...' was reduced to 'never' because property '...' has conflicting types in some constituents

I have a two classes defined as following:我有两个类定义如下:

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;
}

And then I defined a constant which can be one of the classes as following:然后我定义了一个常量,它可以是以下类之一:

const model: FirstClass | SecondClass;

When I call setValues like this:当我这样调用setValues时:

model.setValues(newValues);

I get the following ts error:我收到以下 ts 错误:

  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)

How can I solve this?我该如何解决这个问题?

Edit:编辑:

Here is the link to the playground:这是游乐场的链接:

https://www.typescriptlang.org/play?ts=4.3.5#code/FDDGBsEMGdoAgGIEsBO0AuBhKs4G9g44A3ScAVwFNoAuRVDANTKugBUBPAB0rgF58AXzgx6adMwrVOPANwgi0ShJbUAFKSm0xTVe26UAlHWIB7JABN8hInHQALJNAB0m1v3xxn3t9TiD5IkFgYLAceABlSlBTADsLbBh4AiJfbSiY+MlWGV4BPGFRDLiLbOkDeRslFS0NPTpirL1c4xJzKxTbBydXPQ88Lx8+gJtg0KRY9EoUADNIUF5MUwBbZbiy-R5rWzhLOljyZYAjacDbLhRTHhR0DgBGOgwUCYBzM6ILq+nbgCZH9GesTeIRAlAOyx06AASpQYHEAKLg7a2ACCABo4AAhDGYEHAMGHOCNCwwuGxRGEzpEAAaGIAmhiAFp4iZTWbzXjIcQbXJwSgADym8XgS1W62aBmRKFh0DidC5GFJsvJ4Mq40m0zmCyJ0RKPMlAqFFhFKzWsX1W060rJDV18SVCNVeIgSTgAFkOIlcJ0QDYJkh0GoAPprCyUcDyhhYcJwAA+OsyCXChmRREyGDgofDkfEXvg8eJeY8IdMYfAlR26fQcFilAA7ht+jYdns7mjm+dLtdbg84AByT7d+599s7D5d74cP79weTn4jjtEa3KnOKmWOw7OdEd4JjzOl8POaobNS1ht6QzvfwgQRAA https://www.typescriptlang.org/play?ts=4.3.5#code/FDDGBsEMGdoAgGIEsBO0AuBhKs4G9g44A3ScAVwFNoAuRVDANTKugBUBPAB0rgF58AXzgx6adMwrVOPANwgi0ShJbUAFKSm0xTVe26UAlHWIB7JABN8hInHQALJNAB0m1v3xxn3t9TiD5IkFgYLAceABlSlBTADsLbBh4AiJfbSiY+MlWGV4BPGFRDLiLbOkDeRslFS0NPTpirL1c4xJzKxTbBydXPQ88Lx8+gJtg0KRY9EoUADNIUF5MUwBbZbiy-R5rWzhLOljyZYAjacDbLhRTHhR0DgBGOgwUCYBzM6ILq+nbgCZH9GesTeIRAlAOyx06AASpQYHEAKLg7a2ACCABo4AAhDGYEHAMGHOCNCwwuGxRGEzpEAAaGIAmhiAFp4iZTWbzXjIcQbXJwSgADym8XgS1W62aBmRKFh0DidC5GFJsvJ4Mq40m0zmCyJ0RKPMlAqFFhFKzWsX1W060rJDV18SVCNVeIgSTgAFkOIlcJ0QDYJkh0GoAPprCyUcDyhhYcJwAA+OsyCXChmRREyGDgofDkfEXvg8eJeY8IdMYfAlR26fQcFilAA7ht+jYdns7mjm+dLtdbg84AByT7d+599s7D5d74cP79weTn4jjtEa3KnOKmWOw7OdEd4JjzOl8POaobNS1ht6QzvfwgQRAA

Your code assumes that model is an instance of FirstClass , but the types say that it could be an instance of FirstClass or it could be an instance of SecondClass .您的代码假定modelFirstClass的实例,但类型表明它可能是FirstClass的实例,也可能是SecondClass的实例。 Since it's unclear which it is, but setValues needs to know, TypeScript is highlighting for you that the argument you're passing isn't valid (or perhaps I should say might not be valid).由于不清楚它是哪个,但setValues需要知道,TypeScript 向您强调您传递的参数无效(或者我应该说可能无效)。 And it can't be valid, because it can't be simultaneously both a FirstValuesType and a SecondValuesType (which is what FirstValuesType & SecondValuesType means), since the types of reason differ.不可能是有效的,因为它不能同时是FirstValuesTypeSecondValuesType (这是FirstValuesType & SecondValuesType的意思),因为reason的类型不同。

The minimum-changes way to solve it is to test what you have to see whether it's a FirstClass instance, which you can do since you've used a class (not just an interface).解决它的最小更改方法是测试你必须查看它是否是FirstClass实例,你可以这样做,因为你已经使用了 class (不仅仅是接口)。 So this fixes it:所以这修复了它:

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

Playground example 游乐场示例


That said, you might want to reconsider the overall structure, but it really depends on the specifics and this looks like a simplified example (appropriately simplified, for the purposes of asking the question).也就是说,您可能想重新考虑整体结构,但这实际上取决于具体情况,这看起来像是一个简化的示例(适当简化,以便提出问题)。 FirstClass and SecondClass , and FirstValuesType and SecondValuesType , are identical other than the type of the enum used for reason . FirstClassSecondClass以及FirstValuesTypeSecondValuesType除了用于reason的枚举类型之外是相同的。 You might consider using generic type parameters on a single TheClass and ValuesType instead.您可能会考虑在单个TheClassValuesType上使用泛型类型参数。 But that wouldn't change the fundamental issue that the code in init is assuming that the model is one thing when it may be one or the other of two things.但这不会改变基本问题,即init中的代码假设 model 是一回事,而它可能是两件事中的一个或另一个。


Side note: This part of the init code seems slightly suspicious:旁注:这部分init代码似乎有点可疑:

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

The model constant and the _model parameter point to the same object , so it would be more direct to not create an unnecessary additional identifier and just use _model directly: model常量和_model参数指向相同的 object ,因此不创建不必要的附加标识符并直接使用_model会更直接:

_model.setValues(newValues);

Either way, you're modifying the object that was passed in. (If you meant to copy the object, you'll need to do a copy operation.)无论哪种方式,您都在修改传入的 object。(如果您打算复制object,则需要执行复制操作。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 交集 &#39;xxx &amp; xxx&#39; 被简化为 &#39;never&#39; 因为属性 &#39;xxx&#39; 在某些成分中具有冲突类型 - The intersection 'xxx & xxx' was reduced to 'never' because property 'xxx' has conflicting types in some constituents TypeScript 3.9.5- 交叉点“...”被简化为“从不”,因为属性“使用”在某些成分中有冲突的类型 - TypeScript 3.9.5- The intersection '…' was reduced to 'never' because property 'usage' has conflicting types in some constituents 类型联合被简化为“从不”打断打字:类型被简化为“从不”,因为属性在某些成分中具有冲突类型 - Union of types was reduced to 'never' breaks typing: Type was reduced to 'never' because property has conflicting types in some constituents 在这个 TypeScript 示例中,如何解决“X 被简化为‘never’,因为属性‘Y’在某些成分中具有冲突类型”? - How to resolve "X was reduced to 'never' because property 'Y' has conflicting types in some constituents" in this TypeScript example? Typescript 映射返回类型:交集减少为从不,交集属性冲突 - Typescript mapped return type: intersection reduced to never, conflicting intersection property 交叉点“……”被缩减为从不 - The intersection '…' was reduced to never TypeScript 参数交集减少为从不 - TypeScript parameters intersection reduced to never 为什么交集类型包含冲突类型? - Why can intersection types contain conflicting types? Typescript function参数有两种类型,一种类型的属性不能访问,因为它不是另一种类型的属性 - Typescript function parameter has two types, and the property of one type can't be accessed because it is not a property of the other type setter 中的代理属性从不输入 - Proxy property in setter has never type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM