Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata type not inferred from supplied data. #205

Open
airtonix opened this issue Dec 23, 2024 · 2 comments
Open

Metadata type not inferred from supplied data. #205

airtonix opened this issue Dec 23, 2024 · 2 comments
Labels
wontfix This will not be worked on

Comments

@airtonix
Copy link

Describe the bug

Despite #193 claiming it fixed this issue, installing 2.10.0 reveals that:

  • <TreeView<CustomMetaDataType> /> is not possible
  • <TreeView data={myFlatListOfTypedItems} nodeRenderer={(element) => (...)} /> doesn't infer the type from my items and enforces the default type for metadata.

the index.d.ts has this at the bottom:

declare const TreeView: React.ForwardRefExoticComponent<ITreeViewProps<IFlatMetadata> & React.RefAttributes<HTMLUListElement>>;
export default TreeView;

Which basically just decides it doesn't care what kind of pizza you ordered, you're getting a Margherita.

Screencast.from.2024-12-23.19-13-30.mp4

Where my TocLeaf looks like

type TocLeaf = Omit<INode<{ href: string }>, 'id'> & { id: string };

Code That Causes The Issue

When using forward ref and expecting to allow others to utilise the generic type parameter, you need to do two things:

  1. Not define the component inline with the forwardRef function, instead define it outside with two parameters: props, and ref
  2. use this defined function reference in an exported implementation of forwardRef that is typecast with the return value of function in 1.:
export interface ComponentRef {
  foo: VoidFunction;
}

export type ComponentProps<T> = {
  data: T[];
  onSomething: (data: T) => void;
};

const Component = <T,>(props: ComponentProps<T>, ref: Ref<ComponentRef>) => {
  const foo = useCallback(() => {
    console.log(props.data);
  }, [props]);

  useImperativeHandle(ref, () => ({
    foo,
  }));

  return <div>{props.data.length}</div>;
};

const WithForwardedGeneric = forwardRef(Component) as <T>(
  props: ComponentProps<T> & { ref?: Ref<ComponentRef> }
) => ReturnType<typeof Component>;

export const Foo = () => {
  return (
    <WithForwardedGeneric<{ yes: false }>
      data={[]}
      onSomething={(data) => console.log(data)}
    />
  );
};

image

So to put this in context:

export interface TreeviewComponentRef {
  foo: VoidFunction;
}

// existing types for tree view props. no change needed
export type ITreeViewProps<M extends IFlatMetadata = IFlatMetadata> = { ... }

// 1. define component outside of forwardRef
const TreeViewComponent = <T,>(props: ITreeViewProps<T>, ref: Ref<TreeviewComponentRef>) => {...};

// 2. export the forwardRef, with an enforced type generic and return type.
const TreeView = forwardRef(TreeViewComponent) as <T>(
  props: ITreeViewProps<T> & { ref?: Ref<TreeviewComponentRef> }
) => ReturnType<typeof TreeViewComponent>;

// example using it.
export const MyAmazingApp = () => {
  return (
    <TreeView<{ yes: false }>
      data={[]}
      nodeRenderer={(element) => console.log(data.metadata.yes === false)}
    />
  );
};

However, I'm not smart enough to work out how to make this work with your use of propTypes (i haven't used that concept for nearly 6 years now)

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

@dgreene1
Copy link
Owner

Thanks for the detailed report. The team and I are on vacation for at least a week. But they’ll look at it when we get back.

If you are willing to make a PR, that will speed things up.

cc @mellis481 @yhy-1

Copy link

stale bot commented Feb 21, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants