Home > OS >  Typescript Nested Objects / Json
Typescript Nested Objects / Json

Time:11-19

I'm new to programming and JavaScript, i tried creating an interface for a code challenge, but i keep getting this error message:

Type '{ 1100: { albumTitle: string; artist: string; tracks: string[]; }; 2468: { albumTitle: string; artist: string; tracks: string[]; }; 1245: { artist: string; tracks: never[]; }; 5439: { albumTitle: string; }; }' is not assignable to type 'collectionInfo'.
  Object literal may only specify known properties, and '1100' does not exist in type 'collectionInfo'.ts(2322)

Please i need your suggestions on how to resolve this or how to create a typescript interface that will eliminate this error message.


This my typescript interface attempt:

interface collectionInfo {
        id : {
            albumTitle: string | number |;
            artist: string | number |;
            tracks: string[] | number[] | null; 
        }
}

const recordCollection: collectionInfo = {
    1100: {
      albumTitle: "Prisoner",
      artist: "Lucky Dube",
      tracks: ["Prisoner", "Don\'t Cry"],
    },

CodePudding user response:

You have 2 options.

First is to use [id: number] like this:

interface collectionInfo {
  [id: number] : {
    albumTitle: string | number | null;
    artist: string | number | null;
    tracks: string[] | number[] | null; 
  }
}

const recordCollection: collectionInfo = {
  1100: {
    albumTitle: "Prisoner",
    artist: "Lucky Dube",
    tracks: ["Prisoner", "Don\'t Cry"],
  }
}

And the second way is to add id to properties and then use an array instead like this:

interface collectionInfo {
  id: number;
  albumTitle: string | number | null;
  artist: string | number | null;
  tracks: string[] | number[] | null;
}

const recordCollection: collectionInfo[] = [
  {
    id: 1100,
    albumTitle: "Prisoner",
    artist: "Lucky Dube",
    tracks: ["Prisoner", "Don\'t Cry"],
  }
]

CodePudding user response:

You can do it like this:

interface CollectionInfo {
   [id: number]: {
      albumTitle: string | number;
      artist: string | number;
      tracks: string[] | number[] | null; 
   }
}

try refactoring your interface

interface CollectionInfo {
   id: number;
   albumTitle: string; // I recommend sticking to one type only
   artist: string | number;
   tracks?: string[] | number[]; // if you are trying to add optional property, use ? to make it optional
}

const recordCollection: CollectionInfo = {
   id: 1100,
   albumTitle: "Prisoner",
   artist: "Lucky Dube",
   tracks: ["Prisoner", "Don't Cry"]
}

// Usage
console.log(recordCollection.id); // 1100
console.log(recordCollection.albumTitle); // Prisoner

CodePudding user response:

interface collectionInfo {
        [id: number] : {
            albumTitle: string | number ;
            artist: string | number ;
            tracks: string[] | number[] | null; 
        }
     }

CodePudding user response:

collectionInfo is structured in a way that implies that an instance of this type would be an object containing a single attribute, id, that itself represents an object contains some other attributes.

You need to modify your type definition to allow the object to contain somewhat of a map. These two solutions are equivalent, though I would prefer the second one:

interface CollectionsInfo {
  [id: number]: {
    albumTitle: string | number;
    artist: string | number;
    tracks: string[] | number[] | null; 
  }
}
interface CollectionInfo {
  albumTitle: string | number;
  artist: string | number;
  tracks: string[] | number[] | null;
}

type CollectionsInfo = Record<number, CollectionInfo>;

CodePudding user response:

There are two issues I can notice:

  1. there are trailing pipes | in the interface definition. Although this might not exactly be the problem.
  2. The recordCollection is using 1100 in the place of id which is defined in the interface collectionInfo.

Below is how I think it should look:

interface collectionInfo {
        id : {
            albumTitle: string | number;
            artist: string | number;
            tracks: string[] | number[] | null; 
        }
}
const recordCollection: collectionInfo = {
  id: {
      albumTitle: "Prisoner",
      artist: "Lucky Dube",
      tracks: ["Prisoner", "Don\'t Cry"],
    },
}

Alternatively, if the id must be a number, then you could try this:

interface collectionInfo {
        [key: number] : {
            albumTitle: string | number;
            artist: string | number;
            tracks: string[] | number[] | null; 
        }
}
const recordCollection: collectionInfo = {
  1100: {
      albumTitle: "Prisoner",
      artist: "Lucky Dube",
      tracks: ["Prisoner", "Don\'t Cry"],
    },
}

  • Related