正如您所注意到的,类private
的protected
属性C
不会作为keyof C
. 这通常是可取的行为,因为大多数尝试对具有私有/受保护属性的类进行索引都会导致编译错误。有一个建议允许将类型映射到私有/受保护属性为公共的版本,这将为您提供一种方法来执行此操作……但是从 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
,因为对于该类的外部用户来说是不可见的。您可以使用模块/命名空间仅导出您想要的类的方面,如下所示:
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
,它省略了. 所以你得到了你想要的内部行为,而外部行为类似于。它们不是由于违规而无法访问,而是因为它们不是导出类型的一部分而无法访问。x
keys
_A
NotExported.A
Privates.A
x
keys
private
A
我实际上更喜欢后一种不导出实现细节的方法,而不是暴露属性的存在private
,因为private
属性实际上对如何使用相应的类有很大的影响。也就是说,private
是关于访问控制,而不是关于封装。
好的,希望有帮助;祝你好运!
链接到代码