简体   繁体   English

来自自己财产的动态接口

[英]Dynamic Interface from own property

I wanted to know if this is possible on TypeScript.我想知道这在 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 HeaderOptions 只是一个带有 label 和一个 id 的接口

Is there a way to only allow on datas headers ids given before?有没有办法只允许之前给出的数据标头 id?

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'.我不想只允许只有键“a”和“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
  }))
}

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 .您需要对ComplexTable进行参数化,以便它可以将相同的规则应用于其成员headersdatas
  • You'll need to parameterize HeaderOptions so it can read the keys out of id rather than treating them as a plain string .您需要参数化HeaderOptions以便它可以从id中读取键,而不是将它们视为普通string
  • You'll need to specify datas to take the mapped type [id in K] .您需要指定datas以采用映射类型[id in K]
  • You'll need an identity function so TypeScript can infer the parameters as you construct the table.您需要一个标识 function ,以便 TypeScript 可以在您构建表时推断参数

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 ;请注意,就像在 playground 中一样,TypeScript 不会介意您提供的数据密钥多于它在headers中所知道的数量; however, it will complain if any of the data keys is missing.但是,如果缺少任何数据键,它会抱怨。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM