是的,将属性标记为可选项非常容易,只需在其后添加?
:
class NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
}
或者你也可以使用一个包含 null
或 undefined
的联合类型:
class NavItem {
key: string;
text: string;
target: string;
children: NavItem[] | undefined;
}
话虽如此,但您误解了一件非常重要的事情,这是错误的:
const data: NavItem[] = [
{
key: "dashboard",
target: "dashboard",
text: "Dashboard",
children: []
},
{
key: "sales",
target: "sales",
text: "Sales"
}
];
data
不是一个 NavItem
项目的数组,如果要获取它,您需要使用 new
关键字创建 NavItem
的实例,例如:
const data: NavItem[] = [
Object.assign(new NavItem(), {
key: "dashboard",
target: "dashboard",
text: "Dashboard",
children: []
}),
Object.assign(new NavItem(), {
key: "sales",
target: "sales",
text: "Sales"
})
];
编译器不会因为 TypeScript 基于结构子类型,而对此发出警告,两个类型共享相同的结构。但是,如果在 NavItem 中添加方法,很容易看出这是错误的:
based on structural subtyping.
class NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
getKey() {
return this.key;
}
}
现在尝试使用您的代码:
console.log(data[0].getKey())
你最终会得到以下结果:
未捕获的类型错误:data [0] .getKey不是函数
你甚至会收到编译错误,指出数组项中缺少“getKey”。
如果你只打算将
NavItem
用作数据对象,那么这并不重要,但你应该使用接口或类型别名,因为它们不会编译成js,并且避免了冗余的内存使用。
interface NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
}
编辑
@Zze的一条评论后,我决定添加一个简单的构造函数,使用Object.assign
的“力量”:
class NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
constructor(data?: NavItem) {
if (data) {
Object.assign(this, data);
}
}
}
然后:
new NavItem({
key: "sales",
target: "sales",
text: "Sales"
})
NavItem
创建一个constructor()
呢? - ZzeObject.assign
是有意义的,而不是使用通常的样板构造函数,因为它除了将值分配给成员之外不会做任何其他事情。 - Nitzan TomerObject.assign
的构造函数。 - Nitzan Tomer