Typescript 中的私有继承等效(仅包含或排除特定的类成员或属性)

use*_*840 1 javascript inheritance typescript visual-studio-code typescript-generics

在 Typescript 中模拟私有继承的最佳方法是什么?具体来说,子类想要隐藏父类的某些成员。

例如,预期的解决方法应实现以下目标:

CustomArray<T>从 扩展Array<T>,并且仅隐藏特定pop()成员shift()

let c1 = new CustomArray<number>();
c1.push(10, 20, 30, 40, 50); // okay
c1.shift(); // should error
c1.pop();   // should error
c1.sort(); // okay  etc...
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的,但 vscode 仍然允许应该是受限制的成员。

//Try to hide pop() and push():
type T1<T> = Exclude<Array<T>, 'pop'| 'push'>

// check
let x: T1<number> = [];
x.push(3);  // allowed -- okay
x.pop();    // also allowed -- but wanted it to be an error
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 5

您不想使用继承,因为您不打算允许 aCustomArray<T>以与 an 相同的方式使用Array<T>

您可以做的是将新类型定义为函数Array<T>,并使CustomArray构造函数与运行时的构造函数相同Array

type CustomArray<T> = Pick<Array<T>, Exclude<keyof Array<T>, "shift" | "pop">>;
const CustomArray: new <T>() => CustomArray<T> = Array;

let c1 = new CustomArray<number>();
c1.push(10, 20, 30, 40, 50); // okay
c1.shift(); // error
c1.pop();   // error
c1.sort(); // okay 
Run Code Online (Sandbox Code Playgroud)

按照你要求的方式工作。但请记住,这是 的“浅层”转换Array<T>。例如,该sort()方法仍将返回Array<T>,而不是CustomArray<T>

c1.sort().pop(); // okay
Run Code Online (Sandbox Code Playgroud)

如果您确实想要一个“深度”转换,其中所有相关的提及都Array<T>被替换为CustomArray<T>,您可能需要继续并手动指定完整的接口,因为自动映射不太可能按照您想要的方式工作:

interface CustomArray<T> {
  length: number;
  toString(): string;
  toLocaleString(): string;
  // pop(): T | undefined;
  push(...items: T[]): number;
  concat(...items: ConcatArray<T>[]): CustomArray<T>;
  concat(...items: (T | ConcatArray<T>)[]): CustomArray<T>;
  join(separator?: string): string;
  reverse(): CustomArray<T>;
  // shift(): T | undefined;
  slice(start?: number, end?: number): CustomArray<T>;
  sort(compareFn?: (a: T, b: T) => number): this;
  // ... ALL the other methods, omitted for brevity
} 
const CustomArray: new <T>() => CustomArray<T> = Array;
const c1 = new CustomArray();
c1.push(10, 20, 30, 40, 50); // okay
c1.shift(); // error
c1.pop();   // error
c1.sort(); // okay  
c1.sort().pop(); // error
Run Code Online (Sandbox Code Playgroud)

这比较乏味,但您可以对结果进行更多控制。不过,无论哪种方式都应该适合你。希望有帮助;祝你好运!