typescript 是否有可能创建一个接口,该接口的一个属性与同一对象中的其他属性的子组具有相同的属性?

hk8txs48  于 2023-04-13  发布在  TypeScript
关注(0)|答案(2)|浏览(168)

是否可以在Typescript中创建一个接口或类型,将其中一个属性作为同一对象中其他属性的键的子组类型?
例如,我有这样的基本类型:

interface Node {
   id: string;
   // ...other irrelevant properties
}

interface Connection {
  fromNode: string;
  toNode: string;
  // ...other irrelevant properties.
}

现在我有一个定义为图的接口:

interface Graph {
  nodes: Record<string, Node>
  connections: Record<string, Connection>
  // other irrelevant properties
}

这是一个真实的物体的样本:

const aGrapgh: Graph = {
   nodes: {
       "nodeA": {id: "nodeA"}
       "nodeB": {id: "nodeB"}
   }
   connections: {
      "nodeA": {fromNode: "nodeA", toNode: "nodeB"}
   }
}

这里的问题是,nodesconections被键入为一个带有通用string by键的Record。如果我在connections上使用nodeC,是否有机会以TS抱怨的方式键入它,因为它不是nodes上的现有键?
nodeA这只是一个示例密钥。在真实的代码中,这些Id是在执行时生成的uuid

rxztt3cl

rxztt3cl1#

你追求的是字符串文字类型

interface Graph {
  nodes: Record<'nodeA' | 'nodeB', Node>
  connections: Record<'nodeA' | 'nodeB', Connection>
  // other irrelevant properties
}

type NodeType = 'nodeA' | 'nodeB';

interface Graph {
  nodes: Record<NodeType, Node>
  connections: Record<NodeType, Connection>
  // other irrelevant properties
}

这是相同的,但没有重复。

8oomwypt

8oomwypt2#

你可以使整个图通用,一个字符串联合类型的传递来限制可以使用的节点ID。这不仅会限制你的Record键,还会限制你的Node对象的id属性,以及你的Connection对象的fromNodetoNode属性:

interface Node<T extends string> {
   id: T;
}

interface Connection<T extends string> {
  fromNode: T;
  toNode: T;
}

interface Graph<T extends string> {
  nodes: Record<T, Node<T>>
  connections: Partial<Record<T, Connection<T>>>
}

const graph: Graph<'nodeA' | 'nodeB'> = {
   nodes: {
       "nodeA": {id: "nodeA"},
       "nodeB": {id: "nodeB"}
   },
   connections: {
      "nodeA": {fromNode: "nodeA", toNode: "nodeB"}, // OK
      "nodeB": {fromNode: "nodeB", toNode: "nodeC"}, // Error
   }
}

Playground链接(重命名为NodeGNode,以防止与内置Node类型冲突)

相关问题