当类具有封装的属性时,如何“隐藏类型”对象?

时间:2019-06-15 18:37:50

标签: typescript

我想知道在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的答案...

2 个答案:

答案 0 :(得分:4)

私有使类具有名义上的行为,因此无法使用私有字段对类进行别名。另一方面,我们可以使用Pick删除它们,以仅获取公共属性:

let blogPostItem: Pick<BlogPost, keyof BlogPost>;

blogPostItem = {
    hoverTitle: '',
    summary: '',
    title: ''
}

您还可以使用类型断言来忽略错误。

答案 1 :(得分:2)

要修改@Titian Cernicova-Dragomir的答案,

  

私有使类表现正常。

注意,他说的是“名义上的行为”,而不是“名义上的”。

TypeScript中Class的类型包括私有字段,并在结构上进行比较。这是TS团队做出的一种设计选择,可以避免意外访问或覆盖私有字段。

它确实会造成很多混乱和痛苦,这也是我自己在TS中进行无类编程的主要动力之一。

Pick<>是解决此“限制”的好方法。