【问题标题】:Typescript: Defining an interface with both dynamic and static keysTypescript:使用动态和静态键定义接口
【发布时间】:2021-07-09 13:34:04
【问题描述】:

我正在处理看起来像的数据

{
 8533864186048: "4",
 8533864218816: "1",
 isExchange: true,
 returnType: "exchange",
}

前两个键是动态的,但总是字符串

所以我尝试这样定义接口:

interface ReturnData {
  [key: string]: string; <- Applying this to whole interface for some reason
  isExchange?: boolean;
  returnType?: ReturnType;
  selectedVariant: Variant;
}

因此,尝试在接口上定义动态成员会导致 ts 尝试分配所有其他成员以键入 string

解决这个问题的正确方法是什么?

【问题讨论】:

标签: javascript node.js typescript


【解决方案1】:

你可以这样做:

interface ReturnData {
  isExchange?: boolean;
  returnType?: ReturnType;
  selectedVariant: Variant;
  [key: string]: string | boolean | ReturnType | Variant;
}

但我认为你应该像这样重构你的界面,而不是将动态和静态属性混合在一起:

interface ReturnData {
  isExchange?: boolean;
  returnType?: ReturnType;
  selectedVariant: Variant;
  someProps: {
    [key: string]: string;
  }
}

因此界面更具可读性。

【讨论】:

  • 欢迎来到 StackOverflow!请编辑您的答案以解释此代码的作用以及它如何回答问题,以便对有类似问题的人有用。见:How do I write a good answer?
【解决方案2】:

您可以将所有 number 键限制为字符串:[key:number]: string

type CustomReturnType = string;
type Variant = string;

interface ReturnData {
  [key: number]: string; // <--- any number key should be a string
  isExchange?: boolean;
  returnType?: CustomReturnType;
  selectedVariant: Variant;
}

const data: ReturnData = {
  isExchange: true,
  returnType: 'hello',
  selectedVariant: 'variant',
  2334234234: 'sd',
  234234234:23 // expected error
}

【讨论】:

    【解决方案3】:

    你可以这样定义你的界面

    interface ReturnData {
        isExchange?: boolean;
        returnType?: ReturnType;
        selectedVariant: Variant;
        [key: string]: string | boolean | ReturnType | Variant;
    }
    
    

    如果您只想将编号的键作为字符串,则另一种方法是

    type ReturnData = {
        [key in string | number]: key extends number ? string : string | boolean | ReturnType | Variant;
    } & {
        isExchange?: boolean;
        returnType?: RT;
        selectedVariant: V;
    };
    
    const k: ReturnData = {
        8533864186048: "4",
        8533864186049: "3",
        8533864186048: true // invalid
    };
    

    最终实现将如下所示

    type ValidKeys = "isExchange" | "returnType" | "selectedVariant";
    
    type ReturnData = {
        [key in string | number]: key extends ValidKeys ? string | boolean | ReturnType | Variant : string;
    } & {
        isExchange?: boolean;
        returnType?: ReturnType;
        selectedVariant: Variant;
    };
    

    【讨论】:

    • 有没有办法将额外的键限制为字符串类型?
    • 尝试最新的更新版本。它应该工作
    猜你喜欢
    • 2020-08-22
    • 2020-11-24
    • 1970-01-01
    • 2018-07-03
    • 2012-12-06
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多