最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do i annotate React.forwardRef with jsdoc comments so that intellisense can show up for the underlying componen

programmeradmin3浏览0评论

I have a React ponent written as a function this way:

function Button({ text, icon }) {
  return ...
}

Button.propTypes = {
  text: PropTypes.string.isRequired,
  icon: PropTypes.string.isRequired
}

when using this ponent, I get the autopletion / intellisense in vscode

If i wrap this ponent in React.forwardRef, export default React.forwardRef((props, ref) => <Button btnRef={ref} {...props} />)

then I get the intellisense for the forwardRef function, which does not help my usage, because now there is no way for me to get the props autopleted / show up in intellisense.

I have tried annotating the React.forwardRef with jsdoc extends / augments but to no success, in that case even the default intellisense for forwardRef usage stops showing up. (I believe this is because vscode gives more preference to available types than jsdoc ments). Is there a way for me to get the intellisense for the wrapped ponent working similar to the unwrapped ponent? This would be inline with the understanding that I have for using the wrapped ponent in a similar way as the unwrapped ponent.

I have a React ponent written as a function this way:

function Button({ text, icon }) {
  return ...
}

Button.propTypes = {
  text: PropTypes.string.isRequired,
  icon: PropTypes.string.isRequired
}

when using this ponent, I get the autopletion / intellisense in vscode

If i wrap this ponent in React.forwardRef, export default React.forwardRef((props, ref) => <Button btnRef={ref} {...props} />)

then I get the intellisense for the forwardRef function, which does not help my usage, because now there is no way for me to get the props autopleted / show up in intellisense.

I have tried annotating the React.forwardRef with jsdoc extends / augments but to no success, in that case even the default intellisense for forwardRef usage stops showing up. (I believe this is because vscode gives more preference to available types than jsdoc ments). Is there a way for me to get the intellisense for the wrapped ponent working similar to the unwrapped ponent? This would be inline with the understanding that I have for using the wrapped ponent in a similar way as the unwrapped ponent.

Share Improve this question asked Mar 9, 2021 at 19:26 gaurav5430gaurav5430 13.9k8 gold badges70 silver badges127 bronze badges 2
  • I know how to do this in typescript but I don't know what it looks like with just JSDoc. It seems like you would want to include btnRef as a prop on Button though. – Linda Paiste Commented Mar 9, 2021 at 20:37
  • Yup, btnRef would be a prop to button – gaurav5430 Commented Mar 9, 2021 at 20:43
Add a ment  | 

1 Answer 1

Reset to default 9

It depends how pedantic you want to be about the types. Generally, the use of these ponents is pretty much the same as other functional ponents, so the simplest way is to just declare the type of the result to be a functional ponent. The trick for the props is to first create a variable for the prop types and refer to that for the generic type (or at least, I haven't found a way to make it work without that interstitial value):

/**
 * @type React.FC<ButtonPropTypes>
 */
const Button = forwardRef(({ text, icon }, ref) => (
  <button ref={ref}>{text}{icon}</button>
))

const ButtonPropTypes = {
  text: string.isRequired,
  icon: string.isRequired,
  // `ref` isn't a "real" prop, so `prop-types` will not not actually validate
  // this one, but this adds it to the intellisense list if desired. Feel
  // free to just omit it.
  ref: oneOf(shape({ current: any }), func),
}

Button.propTypes = ButtonPropTypes

If you want to be more accurate, the return type of the forwardRef is actually:

/**
 * @type React.ForwardRefRenderFunction<HTMLButtonElement, ButtonPropTypes>
 */
const Button = forwardRef(({ text, icon }, ref) => (
  <button ref={ref}>{text}{icon}</button>
))

const ButtonPropTypes = {
  text: string.isRequired,
  icon: string.isRequired,
}

Button.propTypes = ButtonPropTypes

However, the IntelliSense doesn't seem to recognize the ref prop (works fine, just isn't in the list).

The definition for the type is here: https://github./DefinitelyTyped/DefinitelyTyped/blob/3423b4fc3e3da09f8acc386bc2fee6fb8f5e0880/types/react/index.d.ts#L559 The first parameter is the expected type for value that will be assigned to the ref. However, since you're not actually statically typing the ref that you would pass in anyway, you might just choose to omit that one with a ?:

/**
 * @type React.ForwardRefRenderFunction<?, ButtonPropTypes>
 */

I think what you mean about the last part is that you wouldn't have both the unwrapped and the wrapped version. That's the typical pattern, as there is no real use for keeping both. However, as an aside, you can directly refer to the propTypes value of any other ponent for use as a generic type such as:

/**
 * @type React.FC<UnWrappedButton.propTypes>
 */

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论