[英]TypeScript class declaration error with private variable
If I have a TypeScript class declaration like this: 如果我有这样的TypeScript类声明:
export class myClass {
constructor(public aVariable: number) {}
private aPrivateVariable: number;
}
and then try to initialize it with: 然后尝试使用以下方法初始化它:
let someVar: myClass[] = [{
aVariable: 3
}, {
aVariable: 2
}];
I get an error (at least in VS Code) saying: 我收到一个错误(至少在VS Code中),说:
Property 'aPrivateVariable' is missing in type '{ aVariable: number; 类型'{avariable:number;类型中缺少属性'aPrivateVariable' }'.
}”。
Why can't I do this? 我为什么不能这样做?
Thanks. 谢谢。
Imagine your class also has a method that uses this field: 想象一下,您的类也有使用此字段的方法:
export class myClass {
constructor(public aVariable: number) {}
private aPrivateVariable: number;
test(){ }
}
Now if you would do the following: 现在,如果您要执行以下操作:
const instance: myClass = {
aVariable: 1,
test() {
alert.aPrivateVariable + 1);
}
};
instance.test();
It would fail. 它会失败。 Therefore, you also need to add private properties.
因此,您还需要添加私有属性。
let someVar: myClass[] = [{
aVariable: 3,
aPrivateVariable: 2,
}, {
aVariable: 2,
aPrivateVariable: 3
}];
Type { aVariable: number; }
输入
{ aVariable: number; }
{ aVariable: number; }
isn't compatible with myClass
{ aVariable: number; }
与myClass
不兼容
As the manual states, 如手册所述,
Private and protected members in a class affect their compatibility.
类中的私有成员和受保护成员会影响其兼容性。 When an instance of a class is checked for compatibility, if the target type contains a private member, then the source type must also contain a private member that originated from the same class.
当检查一个类的实例的兼容性时,如果目标类型包含一个私有成员,那么源类型还必须包含一个源自同一类的私有成员。 Likewise, the same applies for an instance with a protected member.
同样,对于具有受保护成员的实例也是如此。 This allows a class to be assignment compatible with its super class, but not with classes from a different inheritance hierarchy which otherwise have the same shape.
这样一来,一个类就可以与其父类兼容,但不能与其他继承层次结构相同的类的继承兼容。
If myClass
is supposed to be used as interface to assign plain objects that are structurally compatible with myClass
class, separate interface should be provided: 如果应该将
myClass
用作分配与myClass
类在结构上兼容的普通对象的接口,则应提供单独的接口:
interface IMyClass {
aVariable: number;
}
export class myClass implements IMyClass {...}
let someVar: IMyClass[] = [{
aVariable: 3
}];
and then try to initialize it
然后尝试初始化它
It should be noticed that the code above doesn't initialize the class. 应该注意的是,上面的代码并未初始化该类。 It's unclear what were the reasons to assign plain objects instead of class instances, but if
someVar
should contain instances of myClass
, type error indicates the problem. 目前尚不清楚分配普通对象而不是类实例的原因是什么,但是如果
someVar
应该包含myClass
实例,则类型错误指示问题。 Instances should be explicitly instantiated with new
: 实例应使用
new
显式实例化:
let someVar: myClass[] = [new myClass(3)];
Defining the objects in the way you did ( { aVariable: 2}
) does not instantiate them as myClass
objects. 以您的方式定义对象(
{ aVariable: 2}
)不会将它们实例化为myClass
对象。 This is a problem since aPrivateVariable
is not being instantiated because myClass
constructor is never called and the object you add does not match what myClass
contains. 这是一个问题,因为未实例化
aPrivateVariable
因为从不调用myClass
构造函数,并且您添加的对象与myClass
包含的内容不匹配。
As this excerpt from the typescript handbook on type compatibility states : 正如摘录自打字机手册中关于类型兼容性的陈述 :
Private and protected members in a class affect their compatibility.
类中的私有成员和受保护成员会影响其兼容性。 When an instance of a class is checked for compatibility, if the target type contains a private member, then the source type must also contain a private member that originated from the same class.
当检查一个类的实例的兼容性时,如果目标类型包含一个私有成员,那么源类型还必须包含一个源自同一类的私有成员。 Likewise, the same applies for an instance with a protected member.
同样,对于具有受保护成员的实例也是如此。 This allows a class to be assignment compatible with its super class, but not with classes from a different inheritance hierarchy which otherwise have the same shape.
这样一来,一个类就可以与其父类兼容,但不能与其他继承层次结构相同的类的继承兼容。
One way to deal with this is to instantiate every object using something such as map()
一种解决方法是使用诸如
map()
类的方法实例化每个对象。
const someVar: myClass[] = [2,3,1].map(num => myClass(num)) ;
Or, if you're confident of the shape of the object, you can use type coercion: 或者,如果您对对象的形状有信心,则可以使用强制类型:
let someVar: myClass[] = [] as myClass[]
Be careful with this approach though since it does not guarantee that what's contained in the array matches the model of the class. 但是请谨慎使用此方法,因为它不能保证数组中包含的内容与类的模型匹配。
export class myClass {
constructor(public aVariable: number) {}
private aPrivateVariable: number;
}
The correct way would be really initializing your class like this: 正确的方法是像这样真正初始化您的类:
const someVar: myClass[] = [
new myClass(3),
new myClass(2),
]
If you don't initialize your class then you want to get any methods from myClass
, you will end up with object cast as myClass
. 如果不初始化类,那么您想从
myClass
获取任何方法,最终将对象转换为myClass
。
You forgot to declare the class. 您忘了宣布课了。 You can do it like this
你可以这样
const someVar: myClass[] = [new myClass(3), new myClass(2)];
Correct way to initialize this class is - 初始化此类的正确方法是-
export class myClass {
constructor(public aVariable: number) {}
private aPrivateVariable: number;
}
let someVar: myClass = new myClass(3);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.