我需要使用一些类属性名称的子集作为映射中的值,以在类内部使用。在下面的示例中,我将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”'。
答案 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.A
和x
,而是因为它们不是导出的keys
类型的一部分而无法访问它们。
我实际上更喜欢后一种方法,该方法不导出实现细节而不是公开private
属性的存在,因为A
属性实际上对如何使用相应的类有很大影响。也就是说,private
与访问控制有关,而不与封装有关。
好的,希望能有所帮助;祝你好运!