断言接口中的可选属性在编译时在类中不为null

时间:2018-01-21 03:36:04

标签: typescript interface optional-parameters

在Javascript中,我想将.dropdown-submenu a:active { background-color: yellow; }传递给options object,并使用默认值填写我预期的任何缺失属性:

constructor

尝试在Typescript中实现这种模式,我有:

function foo(options) {
   if(options.a == undefined) {
      options.a = 1;
   }
   if(options.b == undefined) {
      options.b = 'hello';
   }
   this.options = options;
}

new foo({a: 10});

当我稍后在interface Options { a?: number; b?: string; } class Foo { options: Options; constructor(options: Options) { if(options.a == undefined) { options.a = 1; } if(options.b == undefined) { options.b = 'hello'; } this.options = options; } } 中使用options时,我知道所有属性都已定义。但是,Typescript不知道这一点,因此该语句会产生错误:

class

此外,我不希望let a:Number = this.options.a; // Argument of type 'number | undefined' is not assignable to parameter of type number. 中的代码稍后为该属性分配classnull值:

undefined

有没有办法定义我的类型,因此在this.options.a = undefined; // should produce compiler error 中使用时Options的属性不可为空而不定义两个class接口< / em>的吗

例如,我知道我可以在内部使用另一个Options

interface

但是我需要在两个独立的接口中定义选项的属性,并确保它们始终保持同步(如果Typescript可以从一个定义生成两个接口,这个解决方案会很棒。)

我也不想将所有属性作为单独的可选参数传递,因为

  1. 可以有数十个或更多选项
  2. 函数参数可能会偏离interface OptionsSafe { a: number; b: string; } // in Foo constructor this.options = { a: a != undefined ? options.a! : 1, b: b != undefined ? options.b! : 'hello' }; 接口,因此我仍然需要保持两个“接口”同步。

1 个答案:

答案 0 :(得分:3)

一种选择是使用Typescript提供的内置Partial类型。这可能太接近于定义两个Options接口&#34;对你而言,无论如何,我会告诉你我的意思。

Typescript提供了一个内置类型Partial,定义为type Partial<T> = {[P in keyof T]?: T[P]}

这意味着你可以做的只是定义所有成员的Options接口,但是使用它的部分版本作为构造函数。像这样:

interface Options {
    a: number;
    b: string;
}

class Foo {
   options: Options;
   constructor(options: Partial<Options>) {
      const defaultOptions = {
          a: 1,
          b: 'hello'
      };

      this.options = Object.assign(defaultOptions, options);
   }
}

为了让Typescript正确地推断出你已​​经拥有了对象的所有必要属性,你需要从你使用的if语句逻辑转移到更像上面的东西。