有什么方法可以在 object 的 Typescript 中指定类型,其中叶子都是一种类型但键名是灵活的?

Is there any way to specify the type in Typescript of an object where the leaves are all one type but the key names are flexible?

想不出一个简单的方式来表达标题,举个例子应该更清楚:

假设我有一个接口:

interface Vehicle {
  color: string;
  year: number;
}

现在我有两个 objects:

const FIRST = {
  cars: {
    a: {color: "red", year: "1980"},
    b: {color: "blue", year: "1991"}
  },
  trucks: {
    red_trucks: {
      c: {color: "red", year: "1990"}
    }
  }
}

const SECOND = {
  collection: {
    new_cars: {
      x: {color: "green", year: "2015"},
      y: {color: "blue", year: "2019"}
    }
  }
}

object 中键的名称和结构不同 - FIRSTcars->a, btrucks->red_trucks- cSECOND 只有 collection->new_cars->x, y。假设会有很多这样的 object,它们都有不同的键名。

但它们还是有点相似,因为 object 实际上只是存储 Vehicle,但它恰好嵌套了一些 object 来做到这一点。

有没有办法在这里指定一个类型,类似于“我们不知道键,但每个键的值是另一个 object 和更多键或 Vehicle” ?某种递归类型?

可以吗?是的。你应该?不,你基本上是在问你能不能禁用类型。

如果不能描述类型,就不能安全地与之交互。打字稿只会妨碍你。 “某种程度的嵌套”是如此模棱两可,你永远不会在打字稿中获得任何价值。

两者之一:更强烈地定义您的概念类型 或者:使用 Record 跳过所有类型的使用,避免使用 typescript

描述这个的类型其实很简单mapped type:

type Tree<T> = {
  [key: string]: T | Tree<T> | undefined
}

我把它写成一个通用的,但在你的情况下 T 将是 Vehicle。对于 Tree 对象的每个 属性,我们说该值是一个 Vehicle、另一个 Tree<Vehicle>undefined。我将 undefined 包括在内,因为在 运行 时您会假设并非每个 属性 都已定义。你应该检查你是否真的有一个值。

您的两个示例都可以分配给 Tree<Vehicle>。在 Playground.

中查看