尝试初始化对象并尝试理解一些怪癖。首先,我想部分初始化对象使用。我在枚举方面遇到了一些奇怪的怪癖。
考虑这种类型层次结构:
enum CalcType {
EXPRESS,
EXPRESS_LESS_EARNED,
COST_BASIS
}
interface Program {
active: boolean;
code: string;
displayOrder: number;
dpld: boolean;
calcType: CalcType;
}
this.p = <Program> {
active: false,
displayOrder: 100,
dpld: true,
calcType: CalcType[CalcType.EXPRESS_LESS_EARNED], // Does not work in Angular!!
//calcType: CalcType['1'] // Works, value is a string
//calcType: CalcType.EXPRESS_LESS_EARNED // Works, value is the ordinal
};
当我尝试使用接口类型创建/初始化新程序时如果我使用CalcType [CalcType.EXPRESS_LESS_EARNED]填充calcType属性,它在JSBin Typescript中工作没有问题,但拒绝在Angular Typescript 2.6.1中工作。有什么想法吗?我得到的错误如下:
Type '{ active: false; displayOrder: number; dpld: true; calcType: string; }' cannot be converted to type 'Program'.
Property 'code' is missing in type '{ active: false; displayOrder: number; dpld: true; calcType: string; }'.
但是,如果我使用CalcType.EXPRESS_LESS_EARNED或CalcType ['1'],它可以正常工作。
JSBin: http://jsbin.com/bipofim/edit?js,console
StackBlitz: https://stackblitz.com/edit/enums-test
我在这里缺少什么?我应该能够使用Enum [ordinal]语法来获取字符串值。另外,为什么它会抱怨在某些情况下缺少字段而在其他情况下缺少字段?
修改
以下是问题,HTTP服务使用语法从JSON反序列化/序列化,其中resp是HttpResponse:
return resp.body as Program;
在反序列化期间,JSON中的字符串将转换为枚举字符串,而不是它们的序数。在序列化期间,他们期望枚举的String等价物,否则它们只会被转换为服务器不理解的数字。
那么如何让JSON根据字符串值或序数来翻译枚举字段?
即。下游“EXPRESS”应转换为CalcType.EXPRESS或1 上游CalcType.EXPRESS或1应转换为“EXPRESS”
答案 0 :(得分:2)
这主要是TypeScript问题。它会在任何地方引起错误,而不仅仅是在Angular中。它适用于JSBin,因为它忽略了编译错误。
这里有两个不同的问题,calcType
和code
属性。
问题是这里使用的枚举不正确,可以通过类型检查来检测。
CalcType
enum被骗了:
var CalcType;
(function (CalcType) {
CalcType[CalcType["EXPRESS"] = 0] = "EXPRESS";
CalcType[CalcType["EXPRESS_LESS_EARNED"] = 1] = "EXPRESS_LESS_EARNED";
CalcType[CalcType["COST_BASIS"] = 2] = "COST_BASIS";
})(CalcType || (CalcType = {}));
它提供了属性名称及其各自数值的映射,并在对象中生成结果:
然而,这是numeric enum,枚举值应该是数字。
这是类型错误,枚举值应该是数字,而CalcType[CalcType.EXPRESS_LESS_EARNED]
是一个字符串:
calcType: CalcType[CalcType.EXPRESS_LESS_EARNED]
这只是禁用类型检查:
calcType: CalcType['1']
这是应该使用枚举的方式,因此它可以工作:
calcType: CalcType.EXPRESS_LESS_EARNED
如果应该能够使用Enum [ordinal]语法来获取字符串值,那么必须使用string enums,并且应该明确定义字符串值:
enum CalcType {
EXPRESS = 'EXPRESS',
...
}
这种方式与普通对象没有什么不同:
const CalcType = {
EXPRESS: 'EXPRESS',
...
};
此错误表明该对象没有code
,而它应该存在于Program
中:
财产代码&#39;类型&#39; {active:false; displayOrder:number; dpld:true; calcType:string; }&#39;
答案 1 :(得分:0)
<强> TLDR:强>
将您的界面更改为以下内容:
interface Program {
active: boolean;
code?: string;
displayOrder: number;
dpld: boolean;
calcType: string;
}
完整答案
我无法准确回答原因,但我可以说如何解决您的一些问题。
您已指定Program
有一个非可选参数code
,然后您无法提供给this.p
。如果您将code
设为可选(code?: string;
),则会使您的错误消息消失,然后您会收到真正的问题(这实际上不是问题!)
就Typescript而言,CalcType.EXPRESS_LESS_EARNED
和CalcType['1']
都返回CalcType
类型的对象。但是,CalcType[CalcType.EXPRESS_LESS_EARNED]
的返回类型为string
。您通过将Program
分配给string
而不是calcType
来违反CalcType
界面。如果您将其更改为calcType: string;
,那么其他问题就会消失。
至于你CalcType[CalcType.EXPRESS_LESS_EARNED]
不起作用的说法,我已经在打字稿2.61和2.71中进行了测试,两次都正确地等同于&#39; EXPRESS_LESS_EARNED&#39;作为string
。