1

I have 2 kinds of Frontmatter:

  • FrontmatterTaxonomy, which is an object with kind: "taxonomy" and a taxnomyName that is a string.
  • FrontmatterContent, which is an object with kind: "content" that should also allow any other keys, as long as their values are string[].

I'm not sure how to model this - so far, I tried it rather simple, which does not work because "content" is not of type "TaxonomyTerms".

How could I achieve this?

type TaxonomyTerms = string[]
type TaxonomyData = Record<string, TaxonomyTerms>
// alternative, doesn't work either
// type TaxonomyData = { [taxonomyTerm: string]: string[] }

type FrontmatterContent = TaxonomyData & {
  kind: 'content'
}

interface FrontmatterTaxonomy {
  kind: 'taxonomy'
  taxonomyName: string
}

type Frontmatter = FrontmatterContent | FrontmatterTaxonomy

// Doesn't work.
// Type 'string' is not assignable to type 'TaxonomyTerms'
const fm1: Frontmatter = {
  kind: 'content',
  tags: ['foo', 'bar']
}

// Works.
const fm2: Frontmatter = {
  kind: 'taxonomy',
  taxonomyName: 'categories'
}
Codepunkt
  • 532
  • 4
  • 15
  • 1
    `FrontmatterContent` is the problematic type; there is no direct support for a "hybrid/rest index signature" of the sort requested in [microsoft/TypeScript#17867](https://github.com/microsoft/TypeScript/issues/17867). There are various refactorings and workarounds. See the [answer](https://stackoverflow.com/a/61434547/2887218) to the [other question](https://stackoverflow.com/questions/61431397/how-to-define-typescript-type-as-a-dictionary-of-strings-but-with-one-numeric-i). If I translate the code there to this question, I get [this](https://tsplay.dev/wgrOvW). – jcalz May 07 '21 at 18:31
  • Awesome, thanks @jcalz Very informative and in-depth! – Codepunkt May 07 '21 at 18:51

0 Answers0