首页 > 解决方案 > 您如何定义具有键字符串索引但具有特定类型的已知键的 TypeScript 接口?

问题描述

您如何定义具有 Key String 索引但具有特定类型的已知键的 TypeScript 接口,以便您可以在映射中引用该键?

示例界面(这不起作用)

interface column {
  label?: string;
  width: string;
}

export interface IColumns {
  [key: string]: {
    title: column;
    objectID?: number;
    url?: column;
    author: column;
    comments: column;
    points: column;
    archive: column;
  };
}

这是这样使用的,

const COLUMNS : IColumns = {
  title: {
    label: "Title",
    width: "40%",
  },
  author: {
    label: "Author",
    width: "30%",
  },
  comments: {
    label: "Comments",
    width: "10%",
  },
  points: {
    label: "Points",
    width: "10%",
  },
  archive: {
    width: "10%",
  },
};

这是我映射转换后的对象以及引用密钥的地方。

const Stories: React.FC<{ stories: IStory[] }> = ({ stories }) => (
  <div className="stories">
    <div className="stories-header">
      {Object.keys(COLUMNS).map((key) => (
        <span key={key} style={{ width: COLUMNS[key].width }}>
          {COLUMNS[key].label}
        </span>
      ))}
    </div>

标签: typescript

解决方案


您可以为可能的键声明一个类型

type Prop = 'title' | 'author' | 'comments' | 'points' | 'archive';

然后接口将使用in关键字将该类型用作计算键

type IColumns = {[key in Prop]: column}

现在您可以使用该界面

const COLUMNS : IColumns = {
  title: {
    label: "Title",
    width: "40%",
  },
  author: {
    label: "Author",
    width: "30%",
  },
  comments: {
    label: "Comments",
    width: "10%",
  },
  points: {
    label: "Points",
    width: "10%",
  },
  archive: {
    width: "10%",
  },
};

关于地图,您有 2 个选项:

  1. 使用Object.keys但将密钥转换为Prop
(Object.keys(COLUMNS) as Array<Prop>).forEach(key => ...)
  1. 使用Object.entries所以value将已经Prop
Object.entries(COLUMNS).map(([key, value /* :Prop */])

操场


推荐阅读