1

I wanted to know if this is possible on TypeScript.

I have an interface like this:

interface ComplexTable extends BaseTable {
    headers: HeaderOptions[];
    datas: { [id: string]: string }[];
  }

And HeaderOptions is just an interface with a label and an id

Is there a way to only allow on datas headers ids given before?

For example I have

const table: ComplexTable = {
  headers: [
    { id: 'a', label: 'Name' },
    { id: 'b', label: 'Last Name' },
  ]
}

I wan't to only allow on datas objects with only the keys 'a' and 'b'.

This should work

const table: ComplexTable = {
  headers: [
    { id: 'a', label: 'Name' },
    { id: 'b', label: 'Last Name' },
  ],
  datas: someData.map((data) => ({
    a: data.someValue,
    b: data.someOtherValue
  }))
}

This should not work

const table: ComplexTable = {
  headers: [
    { id: 'a', label: 'Name' },
    { id: 'b', label: 'Last Name' },
  ],
  datas: someData.map((data) => ({
    a: data.someValue,
    c: data.someOtherValue
  }))
}

1 Answer 1

1

You can do this, but it's going to take some work:

  • You'll need to parameterize ComplexTable so it can apply the same rules to its members headers and datas.
  • You'll need to parameterize HeaderOptions so it can read the keys out of id rather than treating them as a plain string.
  • You'll need to specify datas to take the mapped type [id in K].
  • You'll need an identity function so TypeScript can infer the parameters as you construct the table.

That would look like this:

interface HeaderOptions<K> {
  id: K;
  label: string;
}

interface ComplexTable<K extends string> extends BaseTable {
  headers: HeaderOptions<K>[];
  datas: { [id in K]: string }[];
}

function complexTable<K extends string>(table: ComplexTable<K>) {
  return table;
}

So you can invoke it like this:

const shouldWork = complexTable({
  headers: [
    { id: 'a', label: 'Name' },
    { id: 'b', label: 'Last Name' },
  ],
  datas: someData.map((data) => ({
    a: data.someValue,
    b: data.someOtherValue
  }))
});

Playground link

Note that, as in the playground, TypeScript won't mind if you supply more data keys than it knows to expect in the headers; however, it will complain if any of the data keys is missing.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.