【问题标题】:Infer my object interface to type "object"推断我的对象接口以键入“对象”
【发布时间】:2021-04-24 20:32:16
【问题描述】:

我正在学习 TypeScript。我正在使用使用 TypeScript 构建的库中的组件。我想将我自己的函数传递给这个组件,它作为道具接收它:

import React from "react";
import ForceGraph from "react-force-graph-3d";
import { IProps } from "./interfaces";

export const Graph: React.FC<IProps> = ({ graph, onNodeClick }) => (
  <ForceGraph
    graphData={graph}
    nodeId="publicKey"
    nodeVisibility="visible"
    onNodeClick={onNodeClick}
    linkSource="node1"
    linkTarget="node2"
    nodeResolution={4}
    warmupTicks={25}
    cooldownTicks={0}
    rendererConfig={{
      antialias: false,
      powerPreference: "high-performance",
    }}
    onNodeHover={(d) => console.log(d)}
    enableNodeDrag={false}
  />
);

我正在尝试将onNodeClick 作为道具传递给它。我在组件中做了正确的接口声明:

export interface IProps {
  graph: IGraph;
  onNodeClick?: (node: NodeObject, mouse: MouseEvent) => void;
}

NodeObject是我正在使用的组件的接口,它是:

type NodeObject = object & {
  id?: string | number;
  x?: number;
  y?: number;
  z?: number;
  vx?: number;
  vy?: number;
  vz?: number;
  fx?: number;
  fy?: number;
  fz?: number;
};

node对象接收来自graph的所有属性,而我的node接口是:

export interface INodesFunc {
  publicKey: string;
  alias: string;
  color: string;
  visible: boolean;
}

所以NodeObject 接口应该包含我的node 属性。由于库使用object 类型,我如何将我的node 属性推断为NodeObject

现在我不能在我传递给onNodeClickhandleNodeClick 函数中使用我的node 属性,因为TypeScript 抱怨

“NodeObject”类型上不存在“可见”属性

提前致谢!

编辑:

我的handleNodeClick 函数是

const handleNodeClick = useCallback((node: INodesFunc) => {
  if (adjacencyList[node.publicKey].length <= 1) {
    node.visible = false; // eslint-disable-line no-param-reassign
    setPrunedTree(getPrunedTree());
    return;
  }
  adjacencyList[node.publicKey].forEach((nodeId) => {
    nodesById[nodeId].visible = true;
  });
  setPrunedTree(getPrunedTree());
}, []);

它作为道具传递给我的Graph 组件:

<Graph
    graph={prunedTree}
    onNodeClick={(node: any) => handleNodeClick(node)}
  />

如果我输入node: any,它会起作用,但我想做正确的方式

【问题讨论】:

  • 你在哪里创建handleNodeClick函数?
  • 我在一个页面中创建并将它作为道具传递给我的组件,然后将它作为道具传递给我正在使用的组件
  • 你能添加那部分代码吗?
  • 我编辑了问题

标签: reactjs typescript


【解决方案1】:

看看这是否有帮助:

CodeSandbox link

import * as React from "react";
import "./styles.css";
import ForceGraph from "react-force-graph-3d";
import type { NodeObject } from "react-force-graph-3d";

interface INodesFunc extends NodeObject {  // YOU'ARE EXTENGIN NodeObject TO MEET THE REQUIREMENTS
  publicKey?: string;  // MADE EVERYTHING EXTRA AS OPTIONAL
  alias?: string;
  color?: string;
  visible?: boolean;
}

export default function App() {
  const handleNodeClick = React.useCallback(
    (node: INodesFunc, event: MouseEvent) => {
      return;
    },
    []
  );

  return <ForceGraph onNodeClick={handleNodeClick} />;
}

事实是:

  • 来自&lt;ForceGraph/&gt;onNodeClick 属性期待((node: NodeObject, event: MouseEvent) =&gt; void) | undefined 类型的东西
  • 所以你必须通过满足这些要求的东西。您不能像以前那样在函数参数node 中添加必需的属性,因为&lt;ForceGraph/&gt; 将按照(node: NodeObject, event: MouseEvent) 的合约参数调用该函数。

如果您添加一个名为visible 或其他名称的必需属性,它将显示错误,因为它需要对您说:“您的函数所期望的参数,我不会通过。因为我要传递的NodeObject 没有那个属性”。

这就是为什么将“额外”属性设为可选的原因。因为那时NodeObject 将满足这些要求,即使没有这些属性。

虽然我不完全理解您为什么需要这样做,因为这些属性不是来自 onNodeClick 调用/侦听器处理程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-23
    • 2019-08-12
    • 2021-04-27
    • 2022-07-19
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多