在TypeScript中显式设置可选属性与使用Partial映射类型之间的区别

时间:2019-01-15 04:01:45

标签: typescript types

请考虑以下简化类:

const rect = new Rectangle({
  x: 100,
  y: 100,
  width: 200,
  height: 400,
});

Rectangle构造函数采用一个可选的options对象,其中每个键也是可选的。

有两种方法可以为此options对象编写类型声明:

选项1

编写一个每个属性都是可选的接口

class Rectangle {
  constructor(options?: RectangleConstructorOptions)
}

interface RectangleConstructorOptions {
  x?: number;
  y?: number;
  width?: number;
  height?: number;
}

选项2

在需要键的地方编写一个接口,但与构造函数一起使用Partial映射类型,以使该对象的此属性为可选

class Rectangle {
  constructor(options?: Partial<RectangleConstructorOptions>)
}

interface RectangleConstructorOptions {
  x: number;
  y: number;
  width: number;
  height: number;
}

虽然我了解Partial的工作原理,但很难理解两者之间的区别。 我何时会使用一种方法来替代另一种方法?如果options对象非常大(超过15个属性),那会有什么不同吗?

还,在这种用例中,选项2 被认为是不好的做法吗?

我之所以这样说,是因为这意味着如果要在构造函数之外使用Partial,则这些类型的使用者也必须在调用站点上使用RectangleConstructorOptions

const options: RectangleConstructorOptions = { // ERROR!
  width: 100,
  height: 200,
}

const rect = new Rectangle(options);

1 个答案:

答案 0 :(得分:0)

在此示例中,两者的工作原理相同,但是我认为最好使用Option1。稍后,如果要向接口添加必需的参数,则需要删除Partial并返回Option 1。无论如何。

在这种情况下,我看不出有任何理由使用Partial。例如,对创建生成器类,该类仅占用某些接口的某些必填字段,因此您可以稍后提供其余的内容。

考虑将Partial和其他高级类型用作类型装饰器。仅在已经具有类型并且为了简单起见要对其进行更改时,才应使用它们。在此示例中,您是第一次创建类型,它独立于其他类型。

此外,为避免在选项2中必须在呼叫站点进行局部呼叫,您始终可以创建命名别名:

interface RectangleConstructorOptionsRequired {
  x: number;
  y: number;
  width: number;
  height: number;
}

type RectangleConstructorOptions = Partial<RectangleConstructorOptionsRequired>;

在此处了解有关此主题的更多信息:Advanced Types