不同情况下的可选键

时间:2018-03-09 23:36:42

标签: typescript

在Typescript中是否有办法在不同情况下可选地需要密钥?

例如

interface IDog {
  name: string;
  weight: number;
}

class Retriever implements IDog {
  name = "Dug";
  weight = 70;

  public updateAttribute(props: IDog) {
    ...
  }
}

假设updateAttribute可以获得任何对象:{ name: "" }{ weight: 500 }{ name: "", weight: 30 }{}。现在,我要么必须将?添加到IDog中的每个属性,要么将?添加到(props?: IDog)。两者都不是很好的解决方案,因为我希望Retriever需要属性,我希望每个属性都是updateAttribute中的选项。

有没有办法更新updateAttribute以允许IDog的任何排列,但是仍然需要该类所需的所有属性?

2 个答案:

答案 0 :(得分:2)

听起来你正在寻找Partial类型。部分类型是泛型类型,它使其参数的所有字段都是可选的。所以对你的例子来说:

interface IDog {
  name: string;
  weight: number;
}

class Retriever implements IDog {
  name = "Dug";
  weight = 70;

  public updateAttribute(props: Partial<IDog>) {
    ...
  }
}

应该有效。为清楚起见,Partial<IDog>将等同于类型:

Partial<IDog> = {
  name?: string;
  weight?: number;
}

答案 1 :(得分:1)

CRice的回答是正确的。使用test类型是正确且经济的方法。

但是,值得注意的是,由于TypeScript是一种结构类型语言,Partial<T>子句是一种不影响类型兼容性的形式。 这意味着对于接口

implements

以下是等效的:

interface IDog {
  name: string;
  weight: number;
}

class Dog implements IDog {
  name = "Fred";
  weight = 100;
}

两者都是class Dog { name = "Fred"; weight = 100; } 的实现,按照定义

值得注意的是,IDog暗示TPartial<T>的实现。

因此您也可以编写以下内容(--strictNullChecks假设)

class Retriever {
  name = "Dug";
  weight = 70;

  updateAttribute(props: Partial<this>) {
    Object.assign(this, props);  
  }
}

我们可以通过updateAttribute返回this以有趣的方式进一步概括这一点。

updateAttribute<U extends  Partial<this>>(props: U): this & U {
  return Object.assign(this, props);  
}

允许以下

class Retriever {
  name = "Dug";
  weight = 70;
  age?: number;

  updateAttribute<U extends Partial<this>>(props: U): this & U {
    return Object.assign(this, props);
  }
}

new Retriever().age.toFixed(); // error possibly undefined.
new Retriever().updateAttribute({age: 30}).age.toFixed(); // OK