列出该类的私有属性名称

时间:2019-07-16 22:05:28

标签: typescript private keyof

我需要使用一些类属性名称的子集作为映射中的值,以在类内部使用。在下面的示例中,我将map替换为array。问题在于,如果将属性标记为private,则不会在keyof列表中列出该属性。 如果需要包含私人名称,如何指定密钥类型?

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”'。

1 个答案:

答案 0 :(得分:1)

正如您所注意到的,类private的{​​{1}}和protected属性不会作为C的一部分出现。这通常是理想的行为,因为大多数尝试索引到具有私有/受保护属性的类的尝试都会导致编译错误。有suggestion允许mapping的类型为私有/受保护的属性是公共的版本,这将为您提供一种实现此目的的方法...但是此功能从那时起尚未实现TypeScript 3.5。

所以这不起作用:

keyof C

但是也许您实际上不需要将属性设置为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

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的{​​{1}}属性(和x属性)。因此,您可以获得所需的内部行为,而keys的外部行为类似于_A的外部行为。而不是由于违反NotExported.A而无法访问Privates.Ax,而是因为它们不是导出的keys类型的一部分而无法访问它们。

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

好的,希望能有所帮助;祝你好运!

Link to code