列出 class 的私有 属性 名称
List private property names of the class
我需要使用 class 属性名称的某些子集作为映射中的值以在 class 内部使用。在下面的示例中,我用数组替换了地图。问题是,如果 属性 被标记为 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
}
对于 class 之外的变量和它内部的私有 属性 都存在相同的错误:
Type '"x"' is not assignable to type '"y"'.
如您所见,class C
的 private
和 protected
属性不会作为 keyof C
的一部分出现。这通常是可取的行为,因为大多数使用 private/protected 属性 索引到 class 的尝试都会导致编译错误。有一个 suggestion to allow mapping 类型到 private/protected 属性为 public 的版本,这将为您提供一种执行此操作的方法......但是此功能尚未在 TypeScript 中实现3.5.
所以这行不通:
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
的属性,甚至对 class 的外部用户不可见。您可以使用 module/namespace 仅导出您想要的 class 方面,如下所示:
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
中,class构造函数_A
和对应的类型_A
没有直接导出。在内部,keyof _A
包含 "x"
和 "y"
键。我们导出的是一个构造函数 A
和一个相应的类型 A
,它省略了 x
属性(和 keys
属性) 18=]。所以你得到了你想要的内部行为,而 NotExported.A
的外部行为与 Privates.A
的相似。 x
和 keys
不是由于 private
违规而无法访问,而是因为它们不是导出的 A
类型的一部分而无法访问。
我实际上更喜欢后一种不导出实现细节的方法,而不是暴露 private
属性的存在,因为 private
属性实际上对相应的 classes 可以使用。即private
是访问控制,不是封装。
好的,希望对您有所帮助;祝你好运!
我需要使用 class 属性名称的某些子集作为映射中的值以在 class 内部使用。在下面的示例中,我用数组替换了地图。问题是,如果 属性 被标记为 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
}
对于 class 之外的变量和它内部的私有 属性 都存在相同的错误:
Type '"x"' is not assignable to type '"y"'.
如您所见,class C
的 private
和 protected
属性不会作为 keyof C
的一部分出现。这通常是可取的行为,因为大多数使用 private/protected 属性 索引到 class 的尝试都会导致编译错误。有一个 suggestion to allow mapping 类型到 private/protected 属性为 public 的版本,这将为您提供一种执行此操作的方法......但是此功能尚未在 TypeScript 中实现3.5.
所以这行不通:
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
的属性,甚至对 class 的外部用户不可见。您可以使用 module/namespace 仅导出您想要的 class 方面,如下所示:
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
中,class构造函数_A
和对应的类型_A
没有直接导出。在内部,keyof _A
包含 "x"
和 "y"
键。我们导出的是一个构造函数 A
和一个相应的类型 A
,它省略了 x
属性(和 keys
属性) 18=]。所以你得到了你想要的内部行为,而 NotExported.A
的外部行为与 Privates.A
的相似。 x
和 keys
不是由于 private
违规而无法访问,而是因为它们不是导出的 A
类型的一部分而无法访问。
我实际上更喜欢后一种不导出实现细节的方法,而不是暴露 private
属性的存在,因为 private
属性实际上对相应的 classes 可以使用。即private
是访问控制,不是封装。
好的,希望对您有所帮助;祝你好运!