我想知道在TS中使用访问器是否是一个好习惯,并且我正在测试用例,发现这样做会使您失去“鸭嘴式输入”的“功能”。
是否旨在防止开发人员进行不必要的误操作
还是我错过了什么?
class BlogPost {
constructor(private _title: string, private _summary: string,
private _hoverTitle?: string) {
}
public get title(): string {
return this._title;
}
public set title(value: string) {
this._title = value;
}
public get summary(): string {
return this._summary;
}
public set summary(value: string) {
this._summary = value;
}
public get hoverTitle(): string {
return this._hoverTitle;
}
public set hoverTitle(value: string) {
this._hoverTitle = value;
}
}
let blogPostItem: BlogPost;
blogPostItem = {
hoverTitle = '',
summary = '',
title = ''
}
这应该是有效的分配,但它向我显示以下错误:
类型'{title:string;类型中缺少属性'hoverTitle' _title:字符串;摘要:字符串; _summary:任何; }”,但在“ BlogPost”类型中为必填项。
当我尝试添加这些属性(因为它们是私有的)时,会显示此错误:
Type'{_hoverTitle:any; _summary:任何; _title:任何; hoverTitle:任何;摘要:任何;标题:任何; }”不能分配给“ BlogPost”类型。 属性“ _title”在“ BlogPost”类型中是私有的,但在类型“ {{_hoverTitle:any; _summary:任何; _title:任何; hoverTitle:任何;摘要:任何;标题:任何; }'。
这是想要的还是我缺少什么?
Here is a live preview of the error
我认为这是解决问题的好方法! preview
只需让该类实现一个接口,然后使用该接口进行“鸭子输入” ...这种方式与该类是否封装了私有字段无关紧要,因为您正在键入该接口。
来自@Titian Cernicova-Dragomir的答案...
答案 0 :(得分:4)
私有使类具有名义上的行为,因此无法使用私有字段对类进行别名。另一方面,我们可以使用Pick
删除它们,以仅获取公共属性:
let blogPostItem: Pick<BlogPost, keyof BlogPost>;
blogPostItem = {
hoverTitle: '',
summary: '',
title: ''
}
您还可以使用类型断言来忽略错误。
答案 1 :(得分:2)
要修改@Titian Cernicova-Dragomir的答案,
私有使类表现正常。
注意,他说的是“名义上的行为”,而不是“名义上的”。
TypeScript中Class的类型包括私有字段,并在结构上进行比较。这是TS团队做出的一种设计选择,可以避免意外访问或覆盖私有字段。
它确实会造成很多混乱和痛苦,这也是我自己在TS中进行无类编程的主要动力之一。
Pick<>
是解决此“限制”的好方法。