最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to declare an object with nested array of objects in TypeScript? - Stack Overflow

programmeradmin4浏览0评论

I have two classes like so.

class Stuff {
  constructor() { }
  things: Thing[] = [];
  name: string;
}

class Thing {
  constructor() { }
  active: boolean;
}

I tried to declare a field in my application like this.

blopp: Stuff[] = [
  {name: "aa", things: null}, 
  {name: "bb", things: null}];

The above approach works just fine. However, when I try to provide an array of things, instead of null, I get the error that it's not assignable the the type specified.

blopp: Stuff[] = [
  {name: "aa", things: [{active: true}, {active: false}]}, 
  {name: "bb", things: null}];

I have two classes like so.

class Stuff {
  constructor() { }
  things: Thing[] = [];
  name: string;
}

class Thing {
  constructor() { }
  active: boolean;
}

I tried to declare a field in my application like this.

blopp: Stuff[] = [
  {name: "aa", things: null}, 
  {name: "bb", things: null}];

The above approach works just fine. However, when I try to provide an array of things, instead of null, I get the error that it's not assignable the the type specified.

blopp: Stuff[] = [
  {name: "aa", things: [{active: true}, {active: false}]}, 
  {name: "bb", things: null}];
Share Improve this question asked Mar 6, 2017 at 8:59 Konrad VilterstenKonrad Viltersten 39.1k84 gold badges284 silver badges506 bronze badges 2
  • Actually looks good to me: typescriptlang.org/play/… – deceze Commented Mar 6, 2017 at 9:07
  • @deceze Not sure what to tell you. I got an error message. However, following the suggestion from the accepted answer made the trick. Perhaps mine IDE is more naggy (or yours not naggy enough). Not proficient with TS enough to pass judgment. – Konrad Viltersten Commented Mar 6, 2017 at 13:46
Add a comment  | 

3 Answers 3

Reset to default 11

You should be using the new keyword to instantiate your objects:

class Stuff {
    constructor(public name: string, public things: Thing[] = []) { }
}

class Thing {
    constructor(public active: boolean) {

    };
}

var blopp: Stuff[] = [
    new Stuff("aa", [new Thing(true), new Thing(false)]),
    new Stuff("bb", null)
];

Or simply use interfaces:

interface IThing {
    active: boolean
}

interface IStuff {
    name: string;
    things: IThing[]
}

var blopp: IStuff[] = [
    { name: "aa", things: [{ active: true }, { active: false }] },
    { name: "bb", things: null }];

It is important to determine if you need classes or interface as some things will not work with anonymous objects:

/*
class Stuff {
	constructor(public name: string, public things: Thing[] = []) { }
}
class Thing {
	constructor(public active: boolean) {

	};
}
var blopp: Stuff[] = [
	{ name: "aa", things: [{ active: true }, { active: false }] },
	new Stuff("bb", null)
];
console.log("Is blopp[0] Stuff:", blopp[0] instanceof Stuff);
console.log("Is blopp[1] Stuff:", blopp[1] instanceof Stuff);

*/
var Stuff = (function () {
    function Stuff(name, things) {
        if (things === void 0) { things = []; }
        this.name = name;
        this.things = things;
    }
    return Stuff;
}());
var Thing = (function () {
    function Thing(active) {
        this.active = active;
    }
    ;
    return Thing;
}());
var blopp = [
    { name: "aa", things: [{ active: true }, { active: false }] },
    new Stuff("bb", null)
];
console.log("Is blopp[0] Stuff:", blopp[0] instanceof Stuff);
console.log("Is blopp[1] Stuff:", blopp[1] instanceof Stuff);

try to use <> or the as keyword for casting:

blopp: Stuff[] = [
  {name: "aa", things: [{active: true} as Thing , {active: false}as Thing]}, 
  {name: "bb", things: null}];
}

or

blopp: Stuff[] = [
  {name: "aa", things: [<Thing>{active: true}  , <Thing>{active: false}]}, 
  {name: "bb", things: null}];
}

Further to the accepted answer which is of course correct, if you do want to use interfaces you can define interfaces to go within interfaces like this:

interface IFurniture {
  name: string
  legs: number
}

interface IRoom {
  name: string
  furniture: IFurniture[]
}

interface IHouse {
  rooms: IRoom[]
}

And if you don't don't need the nested parts’ types to be named you can nest the interface definitions:

interface IHouse {
  rooms: {
    name: string
    furniture: {
      name: string
      legs: number
    }[]
  }[]
}

Either of these ways of defining the IHouse interface will strictly type a house definition like below:

let house: IHouse = {
  rooms: [
    {
      name: "kitchen",
      furniture: [
        { 
          name: "chair",
          legs: 4
        },
        { 
          name: "stool",
          legs: 3
        }
      ]
    },
    {
      name: "bedroom",
      furniture: []
    }
  ]
}
发布评论

评论列表(0)

  1. 暂无评论