在角度上下文中对新打字稿不熟悉。您可以在下面的示例中将属性标记为可选吗?您如何建议指定导航项目没有孩子?使用常规JS,我通常会依赖falsey值来检查对象是否具有children
属性。但在Typescript中最好初始化一个空数组?那些可能/可能没有值的原始属性呢?
import { Injectable } from '@angular/core';
export class NavItem {
key: string;
text: string;
target: string;
children: NavItem[];
}
const data: NavItem[] = [
{
key: "dashboard",
target: "dashboard",
text: "Dashboard",
children: []
},
{
key: "sales",
target: "sales",
text: "Sales"
}
];
@Injectable()
export class NavService {
getNav() {
return data;
}
}
答案 0 :(得分:14)
是的,将属性标记为可选项非常容易,您可以在其后面添加?
:
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
项的数组,为了实现这一点,您需要使用{{1}创建NavItem
的实例}}关键字,例如:
new
编译器不会抱怨这样做,因为typescript是based on structural subtyping,并且这两种类型共享相同的结构。
但是通过向const data: NavItem[] = [
Object.assign(new NavItem(), {
key: "dashboard",
target: "dashboard",
text: "Dashboard",
children: []
}),
Object.assign(new NavItem(), {
key: "sales",
target: "sales",
text: "Sales"
})
];
添加方法很容易理解为什么这是错误的:
NavItem
现在尝试使用您的代码:
class NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
getKey() {
return this.key;
}
}
你最终会得到:
未捕获TypeError:data [0] .getKey不是函数
您甚至应该收到编译错误,指出数组项中缺少console.log(data[0].getKey());
。
如果您只打算使用getKey
作为数据对象,那么它并不重要,但您应该只使用接口或输入别名,因为它们不会被编译为js并且您可以避免冗余内存使用:
NavItem
在@Zze的评论之后,我决定添加一个使用interface NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
}
的“权力”的简单构造函数:
Object.assign
然后:
class NavItem {
key: string;
text: string;
target: string;
children?: NavItem[];
constructor(data?: NavItem) {
if (data) {
Object.assign(this, data);
}
}
}