具有条件属性的接口

时间:2019-01-28 19:11:38

标签: typescript class interface

我有一个特殊类型,定义如下:

interface HasNoName {
  hasName: false;
}

interface HasName {
  hasName: true;
  name: string;
}

type MySpecialType = HasNoName | HasName;

是否可以将MySpecialType编写为接口?它必须是一个接口,因为我要一个类来实现它。我不会写:

interface MySpecialType extends HasNoName, HasName {}

出现错误时:

  

“类型为“ HasName”和“ HasNoName”的命名属性“ hasName”不是   完全相同。”

1 个答案:

答案 0 :(得分:2)

您不能真正使接口不是联合类型。但是,如果确实需要,您可以创建类来充当实现联合类型的行为...但是它涉及一些type assertions,因为编译器无法轻松地验证您的工作。

作为一个例子:创建一个实现您可以实际实现的最接近的类的类……类似FilterType = win32com.client.VARIANT(VT_ARRAY|VT_I2, [-4, 0, 0, -4]) FilterData = win32com.client.VARIANT(VT_ARRAY|VT_VARIANT, ['<OR', 'TEXT', 'MTEXT', 'OR>']) selection.SelectOnScreen(FilterType, FilterData)

{hasName: boolean, name?: string}

它有一个overloaded构造函数,用于标记class _MySpecialClass { public hasName: boolean; public name?: string; public constructor(); public constructor(name: string); public constructor(name?: string) { this.hasName = (typeof name !== 'undefined'); this.name = name; } } HasName之间的区别。

然后创建一个名为HasNoName的命名值和命名类型,该类型将声明为您想要的方式。在此示例中,命名类型MySpecialClass只是联合MySpecialClass,而命名值MySpecialTypeMySpecialClass构造函数,断言可以按照您想要的方式运行。

_MySpecialClass

并使用它进行测试:

type MySpecialClass = MySpecialType;    
const MySpecialClass = _MySpecialClass as {      
  new(name: string): HasName;
  new(): HasNoName;
};

嗯,看起来还可以。它有一些疣,但是根据您的用例,它可能适合您。希望能帮助到你。祝你好运!