michael pilote
michael pilote

Reputation: 155

Is there a way to type an object so that all properties of extended interface are a given type?

Im trying to create a type for a dictionary we use. What we do is a bit odd but ill do my best to explain. We have a dictionary in our app that we declare like so:

  localisation: LocalDico = {
    page: ['Page', 'Page'],
    of: ['of', 'de'],
    items: ['items', 'items'],
    itemsPerPage: ['items per page', 'items par page']
  };

where index 0 is english and index 1 is french.

The type LocalDico is the following:

interface LocalDico {
  page: [string, string] | string;
  of: [string, string] | string;
  items: [string, string] | string;
  itemsPerPage: [string, string] | string;
}

the resoning behind this is that in our code we don't want to have to always go like

this.localDico.page[this.language]

so we then proceed to convert this to an object that looks like

//Obviously this is done programatically we dont actually recode everything
localDico: LocalDico = {
  page: 'Page', 
  of: 'Of', 
  items: 'Items', 
  itemsPerPage: 'Items per page'
}

my objective is that if someone creating the localization (the one with the multiple languages) tries to put just a string it raises an error. but someone using the localDico should not have any issues using it as a string.

Bascically i want


interface LocalDico {
  page: string, 
  of: string, 
  items: string, 
  itemsperPage: string
}

and 
interface Localisation{
  page: [string, string],
  of: [string, string],
  items: [string, string],
  itemsperPage: [string, string]
}

Obviously this is a simple dictionary we have some of these with hundreds of entries. i dont want to have to always duplicate the interface i'd rather have one interface that defines all of the keys possible and another that basically says each key for this var is a string or an array containing 2 strings.

sorry for the very long post was just trying to be thorough and clear even though i'm not sure it was. Please let me know if this is unclear

Thanks!

Upvotes: 1

Views: 31

Answers (1)

p.s.w.g
p.s.w.g

Reputation: 149050

Sure, you can use a mapped type, like this:

interface LocalDico {
  page: string, 
  of: string, 
  items: string, 
  itemsperPage: string
}

type Localisation = { [key in keyof LocalDico]: [string, string] };

Or a little cleaner (in my opinion):

// NOTE: an enum would also work here
type LocaleKeys = 
  | 'page'
  | 'of'
  | 'items'
  | 'itemsperPage'

type LocalDico = { [key in LocaleKeys]: string }
type Localisation = { [key in LocaleKeys]: [string, string] }

Upvotes: 2

Related Questions