You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含动态键的对象定义类型并解决分类数组类型赋值问题?

问题:如何为电影数组正确分配分类类型?

原代码

category.ts

interface CategoryType {
  name: string;
  color: string;
}

interface Category extends CategoryType {
  [x: string]: {};
}

export const Categories: Record<string, Category> = {
  action: { name: "Action", color: "#f44336" },
  animation: { name: "Animation", color: "#dcf836" },
  adventure: { name: "Adventure", color: "#233a50" },
  //...
};

slider.tsx

import { Categories } from "@lib/types/category";

export type SliderProps = {
  id: string;
  title: string;
  description: string;
  categories: typeof Categories;
  poster: string;
};

const slides: Readonly<SliderProps[]> = [
  {
    id: "1149",
    title: "Blade Runner 2049",
    // 希望为每部电影添加多个分类
    categories: [Categories.action, Categories.animation],
  },
  //...
];

报错信息

(property) categories: Record<string, Category>
Type 'Category[]' is not assignable to type 'Record<string, Category>'.
  Index signature for type 'string' is missing in type 'Category[]'.ts(2322)
slider.tsx(13, 3): The expected type comes from property 'categories' which is declared here on type 'SliderProps'

问题分析与解决方案

1. 修正Category类型定义

原Category接口的索引签名[x: string]: {}存在类型冲突:name和color都是string类型,但索引签名要求所有属性必须符合{}类型,导致TypeScript无法正确识别这两个属性的具体类型。

  • 如果不需要动态键,直接删除该索引签名即可;
  • 如果确实需要支持额外动态键,要修改索引签名类型以兼容现有属性:
interface Category extends CategoryType {
  [x: string]: unknown;
}

2. 修正SliderProps的categories类型

当前categories: typeof Categories表示属性类型是整个Categories对象(即Record<string, Category>),但实际需要的是分类对象的数组,需将类型改为Category[],也可以用更严格的类型确保数组元素只能是Categories中的分类:

修改后的slider.tsx:

import { Categories, Category } from "@lib/types/category";

export type SliderProps = {
  id: string;
  title: string;
  description: string;
  // 基础写法:Category数组类型
  categories: Category[];
  // 严格写法:仅允许使用Categories中定义的分类
  // categories: (typeof Categories)[keyof typeof Categories][];
  poster: string;
};

const slides: Readonly<SliderProps[]> = [
  {
    id: "1149",
    title: "Blade Runner 2049",
    categories: [Categories.action, Categories.animation],
  },
  //...
];

3. 可选优化:用枚举约束分类键名

为避免拼写错误,可以用枚举定义分类键,让类型检查更严谨:

// category.ts
export enum CategoryKey {
  Action = 'action',
  Animation = 'animation',
  Adventure = 'adventure',
}

interface CategoryType {
  name: string;
  color: string;
}

export type Category = CategoryType;

export const Categories: Record<CategoryKey, Category> = {
  [CategoryKey.Action]: { name: "Action", color: "#f44336" },
  [CategoryKey.Animation]: { name: "Animation", color: "#dcf836" },
  [CategoryKey.Adventure]: { name: "Adventure", color: "#233a50" },
};

在slider.tsx中使用:

categories: [Categories[CategoryKey.Action], Categories[CategoryKey.Animation]],

内容的提问来源于stack exchange,提问作者Mintee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:45:29