【问题标题】:TypeScript interfaces and dynamic keysTypeScript 接口和动态键
【发布时间】:2020-08-22 02:51:09
【问题描述】:

我希望可以做到。

条件很简单——我有两种类型。

type Numbers: Number[];
type Name: string;

假设它们代表我在某处检索到的数据:

// first provider sends it like this
{ "numbers": [2, 3, 4], "name": "Mike" }

// second uses different API keys, even though the data type is the same
{ "numeros": [ 7, 8 ], "nombre": "Jose" }

我不知道 API 创建者如何命名他们的属性,我只知道返回的有效负载将具有 2 个不同的属性 - 一个是 Numbers,另一个是 Name

interface INumbers {
    [propName: string]: Numbers
}

interface INames {
    [propName: string]: Names
}

我知道在属性名称未知的情况下使用索引签名。它还指定可能有超过 1 个属性。我想弄清楚是否可以将INumbersINames 一起加入。

我尝试过联合类型,但实现此接口的对象可能只有 1 个属性。扩展接口的另一个想法也没有奏效。

interface IPayload {
    [propName: string]: INumbers | INames
}

// this will use `[propName: string]` from 1st extended interface, ignoring others
interface IPayload extends INumbers, INames {}

我想知道它是否甚至可以完成。将不胜感激。

谢谢!

【问题讨论】:

  • 如果你在写代码的时候不知道属性名,那么typescript也不能知道。
  • @AlexWayne 好吧,这并不完全正确,我们通过索引签名看到它可以做到,数据的“形状”(或形式)比属性名称更重要。我只希望 [propName: string] 语法适用于 1 个特定属性,而不是所有属性。
  • 你将如何使用这个IPayload 接口?也许这将有助于澄清你的问题。您期望的结果类型是什么?
  • @AlexWayne 这是一个好问题,我应该指定它。我想拥有具有 2 个属性的对象,但我只知道它将拥有什么类型的数据,例如:interface IPayload { [propName: string]: INumbers; [propName: string]: INames; }
  • 但是你如何使用它呢?如果您不知道房产名称,您将如何使用数字访问房产?

标签: typescript oop interface


【解决方案1】:
type NumberListType = Number[];
type NameType = string;

type NumberKeyType = "numbers" | "numeros";
type NameKeyType = "name" | "nombre";

type INumbers = {
  [propName in NumberKeyType]: NumberListType;
};

type INames = {
  [propName in NameKeyType]: NameType;
};

interface IPayload extends Partial<INames>, Partial<INumbers> {}

const pay: IPayload = {
  numeros: [1, 2],
  name: "",
  // numbers: "", Error
  // nombre: [1, 2], Error
};

我试试看,你想要的对吗? 谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 2021-09-16
    • 2020-11-24
    • 1970-01-01
    • 2018-09-04
    • 2021-11-10
    相关资源
    最近更新 更多