首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列出类的私有属性名称。

列出类的私有属性名称。
EN

Stack Overflow用户
提问于 2019-07-16 22:05:28
回答 1查看 2K关注 0票数 6

我需要在映射中使用类属性名称的某些子集作为值,以便在类内使用。在下面的示例中,我用数组替换了映射。问题是,如果属性被标记为private,那么它没有在keyof列表中列出。如果需要包括私名,如何指定密钥的类型?

代码语言:javascript
复制
var keys: Array<keyof A> = ["x", "y"]; // Error

class A {
  private x = 7;
  public y = 8;

  private keys: Array<keyof A> = ["x", "y"]; // Error
}

对于类之外的变量和类中的私有属性,都存在相同的错误:

输入‘x’不能指定键入‘y’。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-17 14:32:56

正如您注意到的,类privateprotected属性C不显示为keyof C的一部分。这通常是可取的行为,因为大多数尝试索引到具有私有/受保护属性的类中都会导致编译错误。有一个建议允许映射类型到一个私有/受保护的属性是公共的版本,这将为您提供一种方法.但是这个特性在TypeScript 3.5中还没有实现。

所以这不管用:

代码语言:javascript
复制
namespace Privates {
  export class A {
    private x: string = "a";
    public y: number = 1;
    private keys: Array<keyof A> = ["x", "y"]; // Error
  }
  var keys: Array<keyof A> = ["x", "y"]; // Error
}
const privateA = new Privates.A();
privateA.y; // number
privateA.x; // error: it's private
privateA.keys; // error: it's private

但是,您可能实际上不需要这些属性是private,而不是类的外部用户所能看到的。可以使用模块/命名空间仅导出所需类的方面,如下所示:

代码语言:javascript
复制
namespace NotExported {
  class _A {
    x: string = "a";
    y: number = 1;
    keys: Array<keyof _A> = ["x", "y"]; // okay
  }
  export interface A extends Omit<_A, "x" | "keys"> {}
  export const A: new () => A = _A;
  var keys: Array<keyof _A> = ["x", "y"]; // okay
}

const notExportedA = new NotExported.A();
notExportedA.y; // number
notExportedA.x; // error: property does not exist
notExportedA.keys; // error: property does not exist

NotExported中,类构造函数_A和对应的类型_A不直接导出。在内部,keyof _A包含"x""y"键。我们导出的是一个构造函数A和相应的类型A,它从_A中省略了x属性(和keys属性)。因此,您得到了您想要的内部行为,而NotExported.A的外部行为与Privates.A的行为相似。xkeys不是由于private冲突而无法访问的,而是因为它们不是导出的A类型的一部分而无法访问。

实际上,我更喜欢不导出实现细节的后一种方法,而不是公开private属性的存在,因为private属性实际上对如何使用相应的类有很大影响。也就是说,private是关于访问控制,而不是关于封装。

好吧,希望这能帮上忙,祝你好运!

链接到代码

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57066049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档