【问题标题】:How to exclude properties from interface while inheriting继承时如何从接口中排除属性
【发布时间】:2019-08-13 18:11:23
【问题描述】:

我有两个接口,XYX 有 2 个属性,x1x2。现在Y 想从X 继承,但不希望x2 被继承。

interface X {
  x1 : string;
  x2 : string;
}

interface Y extends X{
  // x2 shouldn't be available here
}

作为TypeScript 的新人,我想不通。 TypeScript 中是否有任何 extends X without x1 类型的内置功能?

注意:在我的真实案例中,X 是一个内置的interface。所以,我需要在不更改X 接口的情况下执行此操作。有可能吗?

【问题讨论】:

  • 没有。它违反了继承原则。如果汽车是车辆,而车辆有轮子,那么汽车也有轮子。如果您正在设计一辆没有轮子的汽车,那么它不应该扩展 Vehicle。继承很可能不是您应该使用的。
  • @JBNizet 你能给我推荐一个解决这种情况的好方法吗?
  • 不,因为你没有描述情况。
  • 好的。我会根据实际情况编辑问题。
  • @sn42 完全同意。即使我指出了这一点,但我想还不够清楚。

标签: typescript


【解决方案1】:

打字稿>3.5

TypeScript 3.5 引入了 Omit 辅助类型,它创建了一个新类型,其中一些属性从原始类型中删除。来自docs的例子:

type Person = {
    name: string;
    age: number;
    location: string;
};

type QuantumPerson = Omit<Person, "location">;

// equivalent to
type QuantumPerson = {
    name: string;
    age: number;
};

感谢 Jeremy 关于 Typescript 3.5 的更新!

打字稿 >2.8

这可以使用 Typescript 2.1 和 2.8 中引入的 PickExclude 类型来实现:

/**
 * From T pick a set of properties K
 */
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

使用这些类型定义,您可以构造 Omit&lt;T,K&gt; 以省略泛型类型的特定属性:

/**
 * From T pick all properties except the set of properties K
 */
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

说明Typescript 2.8 Release Notes为什么这个类型不包含在Typescript中:

我们没有包含 Omit 类型,因为它写得很简单 作为Pick&lt;T, Exclude&lt;keyof T, K&gt;&gt;

虽然它不包含在 Typescript 中,但有几个库提供了自己的类似Omit 类型,包括react-reduxMaterial-UI

Here 是一个工作示例:

interface X {
  x1: string;
  x2: string;
}

type Y = Omit<X, 'x2'>;

let x: X = {
  x1: 'string1',
  x2: 'string2'
}

let y: Y = {
  x1: 'string1'
}

注意要排除的属性会被检查,排除未在指定类型中定义的属性是错误的:

【讨论】:

  • 如果你想linklink,你可以在答案中添加这个链接
  • 拥有可调试/可播放的代码/代码链接总是更好。另外,如果可能的话,在您回答读者时添加一些参考资料,而不仅仅是 OP
  • 好像可以在import { Omit } from 'react-redux';找到
  • @theapache64 感谢您的评论,@material-ui/core 中也有一个修改版本,实现起来非常简单。使用您喜欢的任何版本。
  • 显然 Typescript 让步了,他们从 3.5.1 开始添加了 Omit:devblogs.microsoft.com/typescript/announcing-typescript-3-5/…
【解决方案2】:
interface X {
  x1 : string;
  x2 : string;
}

class Y implements X{
  x1: string;
  get x2():string {
    return "sorry but x2 is not available here";
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 2017-04-18
    • 2017-10-06
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    相关资源
    最近更新 更多