我刚刚开始使用Typescript,我无法理解是否可以将一个类属性作为一个对象,除了在类中声明的属性之外,它还包含任何属性。例如,我在此处将name
定义为Person
的属性,然后在properties
下,您应该能够为此人定义任何其他任意特征,例如其高度。似乎分配它没关系,但尝试在第12行访问它会引发错误说:
“对象”类型
上不存在属性“高度”
足够公平!我知道不能保证一个名为height
的属性会出现在一个只是一个对象的东西之下,但仍然应该有办法做到这一点。
以下是代码:
class Person {
public name: string;
public properties: Object;
constructor(name: string, other: Object) {
this.name = name;
this.properties = other;
}
}
let props: Object = { height: 200 };
var nick = new Person("Bob", props);
console.log(nick.properties.height);
这是我尝试的另一种选择,它会引发完全相同的错误:
class Person {
public name: string;
public properties: Object;
constructor(name: string, other:{ height: number }) {
this.name = name;
this.properties = other;
}
}
var nick = new Person("Bob", { height: 200 });
console.log(nick.properties.height);
另一种选择我刚试过的界面,但仍无效。
interface PersonProperties {
height: number;
}
class Person {
public name: string;
public properties: Object;
constructor(name: string, other: PersonProperties) {
this.name = name;
this.properties = other;
}
getHeight(): number {
return this.properties.height;
}
}
var properties: PersonProperties = { height: 200 };
var nick = new Person("Bob", properties);
document.write(nick.getHeight().toString());
答案 0 :(得分:5)
由于Person#properties
的静态类型只是Object
,因此类型检查器不会保留任何关于它的其他类型信息,这就是编译错误的原因。您可以通过两种方式解决此问题
any
的“愚蠢”方式:
class Person {
constructor(public name: string, public other: any) {}
/* ... */
}
const p = new Person("doge", { wow : "such property" })
console.log(p.other.wow) // no error, also no type checking
ts中的{p> any
基本上“禁用”类型检查,并允许您访问键入为any
的变量的任何属性
使用泛型的方式稍微聪明一些
class Person<PropType> {
constructor(public name: string, public other: PropType) {}
}
const p = new Person("doge", { wow : "such property" })
console.log(p.other.wow) // ok
console.log(p.other.amaze) // error
这样每个人实例都有一个关联的属性类型,因此如果编译器知道您尝试访问的属性,则会检查“编译”时间。
如果其他语言看起来不熟悉,我建议您阅读一些关于泛型的内容:https://www.typescriptlang.org/docs/handbook/generics.html
答案 1 :(得分:1)
错误的发生是因为您定义了public properties: Object;
而Object
确实没有属性height
。即使您在{ height: number }
属性properties
的构造函数中声明了正确的类型,仍然应该是Object
。
你可以这样做:
type PropertiesObject = { height: number };
class Person {
public name: string;
public properties: PropertiesObject;
constructor(name: string, other: PropertiesObject) {
this.name = name;
this.properties = other;
}
}
let props = <PropertiesObject>{ height: 200 };
var nick = new Person("Bob", props);
console.log(nick.properties.height);
使用界面也是正确的。
请注意,您始终可以使用旧的方括号表示法。即使只使用Object
:
console.log(nick.properties['height']);