#useStore usage with TypeScript

1 messages · Page 1 of 1 (latest)

tired viper
#

I've defined a custom node type like so:

export type RuleNodeData = {
  blockId: number;
  handleOffset?: number;
};
export type RuleNode = Node<RuleNodeData, "ruleNode">;

I'm running into some issues with type support on the useStore hook.
This is how I am using it in my components:

useStore((state: ReactFlowState<RuleNode>) => {})

But I get the following typescript error:

Argument of type '(state: ReactFlowState<RuleNode>) => void' is not assignable to parameter of type '(state: ReactFlowState) => void'.
Types of property 'data' are incompatible.
  Property 'blockId' is missing in type 'Record<string, unknown>' but required in type 'RuleNodeData'.ts(2345)

Can anyone see what I'm doing wrong?

scenic blade
#

useStore is a hook for the entire react flow, not just the node. Why are you passing it a type generic of a particular node.

As the error states the type of useStore is '(state: ReactFlowState) => void'. You can get the info regarding the whole react flow like viewport, edges, nodes info etc from useStore.

gray heath
#

Tbf it could be considered a bug if the jsdocs on useStore is supposed to be accurate since it quite literally shows an example that is the same as what you're trying to do

@example
const nodes = useStore((state: ReactFlowState<MyNodeType>) => state.nodes);

Since this can't work as no generics are passed into ReactFlowState when using useStore the only way to enforce this would be to cast it later

For example:

  useStore((state) => {
    return {
      nodes: state.nodes as RuleNode[],
    }
  });

Still worth opening a ticket on GH though so either the comment for useStore is updated or a generic can be passed down to the ReactFlowState type ^^

tired viper
# scenic blade `useStore` is a hook for the entire react flow, not just the node. Why are you p...

I am aware that useStore is a hook for the entire react flow.

I am trying to pass it a type of a particular node because thats what it says to do in the example in the docs
https://reactflow.dev/learn/advanced-use/typescript#hooks

  // You can type useStore by typing the selector function
  const nodes = useStore((s: ReactFlowState<CustomNodeType>) => ({
    nodes: s.nodes,
  }));

In this guide we exlpain how to work with React Flow and TypeScript.

tired viper
tired viper
#

I'll open up a ticket on GH. I'm not sure if the intention was to be able to pass a node type into the useStore selector, and this a bug, or if we should update the example on the docs