1

I have that JSON 'media' object that looks like this:

const media = [{
    "0": {
        "small": "",
        "large": ""
    }
}];

I have to type it this way:

export interface Media {
    0: {
        large: string
        medium: string
        small: string,
        type: string
    }
}

in order to be able to access it, via element[0].small.

All the JSON objects I am working with are like the following, with an index equals to 0, which is not very useful but I can't change it.

Is there any way I can access my properties just by doing element.small?

k0pernikus
  • 60,309
  • 67
  • 216
  • 347
DevMoutarde
  • 599
  • 7
  • 21
  • 2
    what about using **get/set** functions to modify the behaviour of your properties access ? check [this link](https://stackoverflow.com/a/12850536/8678900) – sohaieb azaiez Feb 28 '21 at 13:25
  • 3
    Why don't you transform them so that the 0-index goes away? You could wrap it in a function `const clean = (elem) => elem[0]`and map all your json objects. – k0pernikus Feb 28 '21 at 14:15
  • thank you for the comments. @sohaieb it may be a bit heavy of a process for such a simple thing ? its a good idea nonetheless. – DevMoutarde Feb 28 '21 at 15:01
  • In the end yes I did as @k0pernikus said, I transformed the element before passing it and then I can have a clean interface type definition. Very easy and simple but I am tired :) thank you – DevMoutarde Feb 28 '21 at 15:02
  • I am gonna delete my question if you don't mind – DevMoutarde Feb 28 '21 at 15:03
  • @DevMoutarde Since you used my approach, I expanded on it in an answer. – k0pernikus Mar 01 '21 at 10:52

1 Answers1

0

You can transform your JSON objects and use them in the simplified form:

const clean = (elem) => elem[0];

You can also gain typescript's type support when doing this, e.g. you can define with a generic:

export interface Raw<T> {
    0: T
}
const transform = <T>(raw: Raw<T>): T => raw[0];

That way you can type your JSON input via Raw<The_Interface_I_Want>;

You can then define interfaces just for the relevant information:

export interface Media {
    large: string
    medium: string
    small: string,
    type: string
}

And then you can use it like so:

const rawMedia: Raw<Media> = {
    0: {
        "large": "large",
        "small": "small",
        "medium": "medium",
        "type": "type"
    }
};

const media: Media = transform<Media>(rawMedia);

Benefit of doing it this way is that you always have type inference and gain autoccompletion this way. In theory, you could also customize the transformation the way you need it.

k0pernikus
  • 60,309
  • 67
  • 216
  • 347
  • Thank you for the thorough answer, some parts are quite difficult to understand as I am new to Typescript as well but thanks to your example following, its getting easier :) – DevMoutarde Mar 01 '21 at 11:12
  • @DevMoutarde On a general note: I recommend checking [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/). It's a great resource and I can only recommend digging deeper into the typing system. Typescript is its own beast, yet its benefits are completely worth it esp. in larger projects. – k0pernikus Mar 01 '21 at 11:18
  • yeah, I often find myself browsing through basarat website ahah, gold mine ! – DevMoutarde Mar 01 '21 at 12:09