8

I'm trying to forward a ref to a Typescript component that does not take any props. When I use React.forwardRef it takes two parameters: props and ref. My component does not use props. How can I declare my component with no linting or compilation errors?

Right now I have:

// this says "props is declared but its value is never used"
const MyComponent = React.forwardRef((props = {}, ref: Ref<HTMLDivElement>): JSX.Element => {
  return (
      <div ref={ref}>
        Fun stuff
      </div>
  );
});

If I declare an empty interface for my props like this:

interface myProps {}

Then I get An empty interface is equivalent to '{}' but then when I try to declare with just {} and no actual interface then I get:

Don't use `{}` as a type. `{}` actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.
- If you want a type meaning "any value", you probably want `unknown` instead.

Is there some way that I can declare an interface/type for these props which expects an empty object and doesn't cause me linting issues?

Update: When I use an empty object type as recommended from this issue thread, it causes a type error where the component is used.

Type '{ ref: RefObject<HTMLDivElement>; }' is not assignable to type 'Pick<NoElements<Record<string, never>>, string>'.
  Property 'ref' is incompatible with index signature.
    Type 'RefObject<HTMLDivElement>' is not assignable to type 'never'.

Shows at:

<MyComponent ref={refToForward} />

Seems like there's a chicken egg situation.

1
  • what if you used React.forwardRef<HTMLDivElement, any>() instead? Commented Oct 20, 2020 at 20:49

3 Answers 3

6

If you want to use forwardRef but don't need props, you can try this:

const MyComponent = forwardRef((_: unknown, ref: Ref<HTMLDivElement>) => {
  return (
      <div ref={ref}>
        ...
      </div>
  );
});
Sign up to request clarification or add additional context in comments.

1 Comment

Changing from _props: undefined to _props: unknown fixed it for me.
0

You could prefix the props with an underscore like this _props to get rid of props is declared but its value is never used.

And for the empty interfaces I usually use types, so, in your case, that would be type myProps = {}.

UPD:

How about we pass the types into the <>, like:

type Props = {};

const MyComponent = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
  return (
      <div ref={ref}>
        Fun stuff
      </div>
  );
});

8 Comments

Using a type still gives me an error: Don't use {} as a type. {} actually means "any non-nullish value". - If you want a type meaning "any object", you probably want Record<string, unknown> instead. - If you want a type meaning "any value", you probably want unknown instead.
Ok, so I looked into it and it appears you're using typescript-eslint config. Basically, what are you trying to do is not encouraged in the comments of the repo, but you could always // eslint-disable-next-line to get rid of the messages or reconfigure your .eslintrc file: { "rules": { "@typescript-eslint/ban-types": [ "error", { "extendDefaults": true, "types": { "{}": false } } ] } }
Basically, what are you trying to do is not encouraged in the comments of the repo. What exactly isn't encouraged? Do you have a link? Is an alternative suggested somewhere?
Sure, here it is github.com/typescript-eslint/typescript-eslint/issues/… look at the last section of the comment by bradzacher and let me know if it means something else, cause I would want to know too :)
I guess the recommended way would be to define props of the component, but since you want to omit them it's better to either reconfigure the eslint or disable that particular rule on that particular line
|
0

For me, it worked with an underscore after using ref due to this lint rule after-used argument at https://eslint.org/docs/latest/rules/no-unused-vars#args-after-used which roughly states that the previous param will not be checked if the next one is used. I know it's a little late question but hope this answer helps someone though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.