2

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.

1
  • 1
    As far as I'm aware there's no way to enforce that at compile time. Commented Nov 10, 2020 at 12:50

2 Answers 2

2

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.

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

1 Comment

Thank you for your reply. Your solution looks reasonable and in fact, this is the only way to achieve safe column identification. In fact, I also considered this option and came to the conclusion that when adding or changing a field during iteration in an imperative or functional way, it is possible to accidentally re-sort the columns. Rather, I still need to add the sort field.
1

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

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.