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

Posted

技术标签:

【中文标题】Typescript 中的私有继承等价物(仅包括或排除特定的类成员或属性)【英文标题】:Private inheritance equivalent in Typescript (Only including or excluding specific class members or properties) 【发布时间】:2019-09-04 08:54:33 【问题描述】:

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

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

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...

这是我尝试过的,但 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

【问题讨论】:

Typescript hide props from super class的可能重复 @DerekBrown 虽然它可能接近重复,但提供的答案是旧的并且无关紧要。但是,下面这个问题的答案解决了这个问题。 【参考方案1】:

您不想使用继承,因为您不想让CustomArray&lt;T&gt; 以与Array&lt;T&gt; 相同的方式使用。

您可以做的是将您的新类型定义为Array&lt;T&gt; 的函数,并使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 

按照您的要求进行。但请记住,这是Array&lt;T&gt; 的“浅层”转换。例如,sort() 方法仍将返回 Array&lt;T&gt;,而不是 CustomArray&lt;T&gt;

c1.sort().pop(); // okay

如果您真的想要一个“深度”转换,将所有与 Array&lt;T&gt; 相关的提及都替换为 CustomArray&lt;T&gt;,您可能需要继续手动指定完整界面,因为自动映射不太可能以这种方式工作你想要的:

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

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

【讨论】:

以上是关于Typescript 中的私有继承等价物(仅包括或排除特定的类成员或属性)的主要内容,如果未能解决你的问题,请参考以下文章

Typescript中的类

C++ 中的默认继承模式(公共、保护或私有)是啥? [复制]

Typescript 解析私有范围包的类型

C# 中的 C++ 模板继承等价物是啥?

TypeScript中的指令,编译(前/后)的等价物是啥?

Flow 中星号 (*) 类型的用途是啥,TypeScript 中的等价物是啥?