interface unique value in item of array using TypeScript

Viewed 818

I am gradually learning React using TypeScript. I constantly face the problem of describing objects so that ESLint can prompt me. I am trying to describe an object in an array so that its field name was with a unique value from a possible enumeration IKeyNameColumns . To make it easier for me to understand what I mean, I'd better give an example:

type IKeyNameColumns = 'name' | 'status' | 'type' | 'age'

interface IListColumns {
  columns: Array<{
    title: string
    name: IKeyNameColumns // need only one uniq value of IKeyNameColumns 
  }>
}

I understand that it is rather done with the help of Generics and rather has something to do with the collection Set.

2 Answers

I don't think you can achieve this using arrays, but arrays are the same as objects.

I would approach your probleme as follow:

type IKeyNameColumns = 'name' | 'status' | 'type' | 'age'

interface IColumn {
  title: string
}

type IListColumns = { [K in IKeyNameColumns]: IColumn }

const listColumns: IListColumns = {
  name: { title: "Name Title"},
  status: { title: "Status Title"}
}

This way you cannot duplicate keys, nor you can add unknown IKeyNameColumns. (see)

If you need to iterate on listColumns you can use for...in.

So as I understand you try to tell IListColumns that the columns array is not allowed to have 2 elements with the same name property.

As far as I know that is not possible with generics and should be solved with a Set, which you also mentioned in your question.

That leads to the next problem, Set has, as far as I know, no possibility to define a comparator, which would indicate a equalness in case of equal name property and instead always check the whole object.

The same is also discussed here: How to customize object equality for JavaScript Set

Related