0

I would like to create a Typescript Interface for objects like these:

{
  "id": 34728,
  "url": "https://example.com/image.jpg",
  "commonNames": {
    "de": ["Apfel", "Kulturapfel"],
    "en": ["apple"],
    "th": ["แอปเปิล"]
  },
}

Is my approach correct? I'm especially unsure about the commonNames.

interface Food {
  id: number;
  url: string;
  commonNames: {
    [index: string]: string[];
  };
}
3
  • 1
    Is there a predefined list of commonName keys ('de', 'en', 'th'), or could it be literally any string and you won't know which ones until runtime? If it's any string, then you've done it correctly. Commented May 9, 2020 at 5:01
  • Yes thanks, it could be any string. How would it look like if I later decided to add a predefined list of CommonName keys? Commented May 9, 2020 at 5:06
  • There's a couple options, but i'd probably define a union type with the various strings, then use that. eg: type Language = 'de' | 'en' | 'th' and commonNames: { [index in Language]: string[] } Commented May 9, 2020 at 5:15

1 Answer 1

2

As already confirmed in @Nicholas Tower's comment, your approach is correct.

There is, however, a small improvement I would like to suggest: you have three strings in your type definition. However, those three strings actually mean completely different things. So, what I would do, is give them a type alias:

type Uri      = string;
type Language = string;
type Name     = string;

interface Food {
  id: number;
  url: Uri;
  commonNames: {
    [index: Language]: Name[];
  };
}

These are only aliases, so they do not actually change anything about the typing. But, they make it a little bit clearer what those attributes are about.

Also, a type alias gives you a place that you can attach a TSDoc comment to:

/**
/ * A globally unique, monotonically increasing identifier for a dictionary entry
**/
type Id         = number;

/**
/ * A URI
**/
type Uri        = string;

/**
/ * A URI referencing a picture of the food
**/
type PictureUri = Uri;

/**
/ * An ISO 639-1:2002 Alpha-2 Language Code
**/
type Language   = string;

/**
/ * The name of the food
**/
type Name       = string;

interface Food {
  id: Id;
  url: PictureUri;
  commonNames: {
    [index: Language]: Name[];
  };
}

This is of course an extreme example, but it shows the value of type aliases for documentation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.