打字稿,什么是声明具有不同类型的嵌套对象的最佳方法?

时间:2016-10-12 07:35:24

标签: javascript typescript typescript-typings

我有这个JS对象,我想把它移植到Typescript:

var items = [{
      style: 'activity-8',
      color: '#a32c62',
      id:    8,
      done : false,
      label : {
        short :'999 m',
        long  :'walk 999m',
        statstime  :'yesterday'
      },
      val : {
        today : {
          target   : { 
            raw : 0,
            display :"11"
          },
          achieved : {
            raw : 0,
            display :"22"
          }
        },
        yesterday : {
          target   : {
            raw : 0,
            display :"33"
          },
          achieved : {
            raw : 0,
            display :"44"
          }
        }
      }
    },{
      style: 'activity-7',
      color: '#ec575d',
      id:    7,
      done : true,
      label : {
        short :'walk 555m',
        long  :'walk 555m',
        statstime  :'yesterday'
      },
      val : {
        today : {
          target   : { 
            raw : 0,
            display :"0"
          },
          achieved : {
            raw : 0,
            display :"0"
          }
        },
        yesterday : {
          target   : {
            raw : 0,
            display :"0"
          },
          achieved : {
            raw : 0,
            display :"0"
          }
        }
      }
    }];

声明此对象类型的最佳方法是什么?我应该写下每个领域的类型吗?或者创建一个自定义类型?还有其他建议吗?

2 个答案:

答案 0 :(得分:2)

我不知道它是否是最好的"方式,但我会举例说明我这样做的方法。

我将尝试不仅针对嵌套对象解释我的一般规则:

对于基本类型的所有属性(字符串,数字,布尔值或某些某些数组),您可以像这样保留它们,但对于从现在开始的每个其他复杂属性/嵌套对象,我将调用'复杂的财产' (因为它对我来说更有意义)你创建了一个属性类型的接口。

示例:在您的情况下,val属性是一个复杂的'财产让我们分开它,从下到上。

val属性中最小的复杂属性是target,因此你创建一个名为Target的接口(或者ITarget它不是一个在ts中完成的约定)Target将是这样的:< / p>

interface Target {
  raw: number,
  display: string
}

你对achieved&#39;复杂&#39;做同样的事情。属性。

现在你可以升级一级了。 Today财产也是一个复杂的&#39;一,所以它必须有一个可能会成为某种类型的接口的类型。感谢我们之前的工作,界面将如下所示:

interface Day {
  target: Target,
  achieved: Achieved
}

您可能想知道为什么界面被称为Day而不是Today,原因是您必须找出yesterday&#39;复杂&#39;的类型。属性。如您所见,您可以看到它与today属性的类型相同,因为它内部具有相同的属性。

所以最后我们的目标val属性将拥有它自己的界面,如下所示:

interface Val {
  today: Day,
  yesterday: Day
}

接下来,你会为其他所有复杂的事情做同样的事情。属性。

现在你可以在你的主要对象中使用那些可能是一个类及其属性的对象。类型将是那些接口。

别忘了ts(而不仅仅是)中的界面只是帮助&#39;只有助于组织代码设计的工具。大多数时候,每个接口都必须有一个实现该接口的类。这些是您将用于实际为这些属性设置一些值的类。

答案 1 :(得分:0)

如果您不想提取子类型(嵌套字段作为单独的类-es),因为它们仅在一个地方使用,那么请按以下方式定义类(从头开始的代码)

export class MyItem {
  style: string;
  color: string;
  id: number;
  done: boolean;
  label: {
    short: string,
    long: string,
    statstime: string
  };
  // ... and so on


  constructor(item: any) {        
    if(item) Object.assign(this, item); // copy item fields to "this" fields
  }
};


// and map your not-typed items table (eg readed from API) to typed
let typedItem: MyItem[] = items.map(item => new MyItem(item));