将接口的密钥类型限制为另一个接口的值的类型

时间:2020-03-29 14:58:57

标签: typescript

This playground example描述了我要执行的操作,但实际上,我试图将一个对象的可能键限制为另一个对象的值。

这可能吗?

3 个答案:

答案 0 :(得分:0)

我能得到的最接近的是这个

type accessor = "surname" | "firstname"

interface IData { 
  title: string;
  accessor: accessor;
}

type ICell = Record<accessor, string>

答案 1 :(得分:0)

在TypeScript中无法根据运行时值定义类型,因为在运行时会删除所有类型。您要的是完全不可能的。

考虑:如果从返回随机值的Web服务器获取此对象怎么办?编译将如何工作?您需要连接到互联网吗?因为没有运行时类型检查,所以它根本不起作用。

要在运行时完成此操作,如您所愿,可以使用普通的javascript。例如:

const accessors = data.map(o => o.accessor);

for (const cell of cells) {
    for (const key in cell) {
        if (!accessors.includes(key)) {
            // throw a runtime error
            throw new Error("This key is not a valid accessor!"); 
        }
    }
}

答案 2 :(得分:0)

如果知道编译时IData的类型,则可以种类。因此,您将需要以下内容:

const data = [
  {
    title: "First name",
    accessor: "firstname",
  },
  {
    title: "Last name",
    accessor: "surname",
  }
] as const

type Accessors = typeof data[number]["accessor"]

type ICell = Record<Accessors, string>

const cells: ICell[] = [
  {
    firstname: "Davy",
    surname: "James"
  },
  {
    firstname: "Billy",
    surname: "Cricket"
  }
]

如果您在编译时不知道data的结构,就像其他答案指出的那样,则不能这样做。同样(与其他任何对象一样),您还必须检查在运行时创建的任何其他数据是否适合ICell数据类型,并且如果要这样做,则无法在运行时实际检查它。