簡體   English   中英

來自自己財產的動態接口

[英]Dynamic Interface from own property

我想知道這在 TypeScript 上是否可行。

我有一個這樣的界面:

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

HeaderOptions 只是一個帶有 label 和一個 id 的接口

有沒有辦法只允許之前給出的數據標頭 id?

例如我有

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

我不想只允許只有鍵“a”和“b”的數據對象。

這應該工作

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

這不應該工作

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

你可以這樣做,但這需要一些工作:

  • 您需要對ComplexTable進行參數化,以便它可以將相同的規則應用於其成員headersdatas
  • 您需要參數化HeaderOptions以便它可以從id中讀取鍵,而不是將它們視為普通string
  • 您需要指定datas以采用映射類型[id in K]
  • 您需要一個標識 function ,以便 TypeScript 可以在您構建表時推斷參數

那看起來像這樣:

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;
}

所以你可以像這樣調用它:

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

游樂場鏈接

請注意,就像在 playground 中一樣,TypeScript 不會介意您提供的數據密鑰多於它在headers中所知道的數量; 但是,如果缺少任何數據鍵,它會抱怨。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM