我有两个类定义如下:
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
您的代码假设model
是FirstClass
的一个实例,但是类型表明它可能是FirstClass
的一个实例,也可能是SecondClass
的一个实例。由于不清楚它是哪个,但setValues
需要知道,TypeScript会为你突出显示你传递的参数是无效的(或者我应该说可能不是是有效的)。它不可能是有效的,因为它不能同时是FirstValuesType
和aSecondValuesType
(这是FirstValuesType & SecondValuesType
的意思),因为reason
的类型不同。
解决这个问题的最小更改方法是测试你必须看到它是否是FirstClass
实例,你可以这样做,因为你已经使用了一个类(而不仅仅是一个接口)。所以这个修复了它:
if (model instanceof FirstClass) {
model.setValues(newValues);
} else {
// ...code here to do something with the `SecondClass` `model`
}
操场例子
也就是说,您可能需要重新考虑整个结构,但这实际上取决于具体情况,这看起来像是一个简化的示例(为了提问的目的,进行了适当的简化)。FirstClass
和SecondClass
,以及FirstValuesType
和SecondValuesType
,除了reason
使用的enum类型外,其他都是相同的。您可以考虑在单个TheClass
和ValuesType
上使用泛型类型参数。但这不会改变一个基本问题,即init
中的代码假设模型是一回事,而它可能是两件事中的一件。
旁注:init
代码的这一部分似乎有点可疑:
const model: TheClass<EnumType> = _model;
// ...
model.setValues(newValues);
model
常量和_model
形参指向同一个对象,所以不创建不必要的额外标识符,直接使用_model
会更直接:
_model.setValues(newValues);
无论哪种方式,都是在修改传入的对象。(如果要复制对象,则需要执行复制操作。)