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
[@types/react] useRef return type clashes with ref prop type #35572
Comments
EDIT 2: Disregard my solution, use the one below :) I currently have the same problem, have you found a solution already by any chance? EDIT: I'm now using this, admittedly not so pretty, solution: const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>; Found here: #28884 (comment) |
A slightly neater solution is to set the initialValue to null in the useRef function call
this ensures that componentRef = |
@shane935 you have made my day sir 🙌🏻 |
Seems to me //index.ts, line 80
interface RefObject<T> {
readonly current: T | null;
} so it reads //index.ts, line 80
interface RefObject<T> {
readonly current: T | null | undefined;
} |
It's not a bug, it's catching a legitimate typing error. For more details, see #38228 (comment) |
Just as @Jessidhia say, it's not a bug , maybe you should write like this.
|
I'm not sure this will fix everyone's problem, and I'm no expert on this stuff, but after looking at the typings of what I was passing in as a ref and the actual ref type of the component I was passing the ref into, it seemed as though I had the interfaces wrong. I initially had an interface of props like so for the receiving component:
which I changed to:
the typing error then disappeared. I'm not going to pretend I know more than I do, but looking into the typings for the HTMLProps interface and the React.forwardRef() function type you can see that it is using RefAttributes. Just above that, you can see the ClassAttributes type that HTMLProps is extending, of which defines the LegacyRef type which I believe was causing my typing issue. |
It looks like this project has 3 overloads for
|
I have I pass it to my I try to consume w/ I'm now unable to consume the @Jessidhia @osf2e your suggestion does not seem applicable here. The workaround I've had to resort to: if (ref && (ref as RefObject<HTMLDivElement>).current) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(ref as RefObject<
HTMLDivElement
>)!.current!.style.height = `${containerHeight}px`;
} |
Using react-native-web, I had to use. import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View> |
I had this problem with a Ref for an |
@joshribakoff You can also type the parameters directly
That way you shouldn't have to typecast when accessing your ref. |
I used this when passing a ref to a form:
|
Hi thread, we're moving DefinitelyTyped to use GitHub Discussions for conversations the To help with the transition, we're closing all issues which haven't had activity in the last 6 months, which includes this issue. If you think closing this issue is a mistake, please pop into the TypeScript Community Discord and mention the issue in the |
I feel like I'm losing my @#$%ing mind here, coz @shane935 received a lot of love for his comment, but it produces the exact same error for me! Honestly, I feel like the entire move to TypeScript from vanilla JS has been a constant battle against the over-complicated strictness of the compiler. Now I'm stuck between a rock and a hard place: do I go back to JS and relish in the fact that simple statements like this just work, or do I continue on this epic journey of trying to produce "safer" code? If I was working on a project for my boss, the answer would be obvious: @#$% off TS and go back to actually getting work done, instead of wasting (potentially) weeks on this constant fight with the TS compiler. But I'm working on my first TS project "just for fun", and although I'm not having much fun ATM, I feel as though this shouldn't be so hard and that the benefits should outweight the effort required. IDK though...what do you guys think?? |
I know what you mean @kenny1983 had similar feelings when I was starting out in TS also :) One 'pro' argument to static checking I've seen, but can be hard to appreciate as a developer first starting out with TS and feeling suffocated by the type checker, is that when your code is typed properly, TS static checks should in principle forestall a whole category of exceptions your end users might otherwise encounter without your awareness. Reason you might never know about it is, unlike on the server side, JS errors in the browser don't get sent to a server by default (not without you setting up some kind of analytics/error reporting etc). As you know with SPAs, including React, unhandled exceptions can be quite devastating b/c the whole app may unexpectedly just "turn white"/crash, depending. TS should help avoid at least some of the reasons for this. |
Thanks @onpaws for both the empathy and the example of how TS is worth the effort 👍. After writing the wild rant above (LOL lets face it, that's what it was 😛) I ended up spending the rest of my night and well into the early hours of the morning reading blogs re: why people love or hate it, then listening to a podcast from Scott Hanselman where he talks to Anders Hejlsberg about his intentions behind creating the language. I thoroughly recommend a listen! Another great resource is this keynote presentation from the GOTO Conference 2012 where Anders demonstrates the power of static typing-powered tools. I already knew this having come from a C# background, but it never actually dawned on me why C# IntelliSense and the equivalent IDE features for JS are so far apart in what they can achieve. Very cool! 😎 So I think I'll keep using TS as Anders originally intended: a smart tooling enabler and nothing more. After all, compiled TS is just JS without the type annotations anyway, right?? And if/when I find myself wrestling the type checker again, I'll just throw a |
There is another way to solve the problem: export const Input = forwardRef<HTMLTextAreaElement, IInputProps>((props, ref) => {
const inputRef = useRef<HTMLTextAreaElement | null>()
const createRef = (node: HTMLTextAreaElement | null) => {
inputRef.current = node
if (typeof ref === 'function') {
ref(node)
} else if (ref) {
(ref as React.MutableRefObject<HTMLTextAreaElement | null>).current = node
}
}
const clickUploadFileHandler = useCallback(() => {
if (inputRef) {
inputRef.current?.focus()
}
}, [])
return (
<>
<s.Input ref={createRef} />
<FileUpload files={files} onClick={clickUploadFileHandler} />
</>
)
}) |
See for where the solution came from DefinitelyTyped/DefinitelyTyped#35572 (comment)
See for where the solution came from DefinitelyTyped/DefinitelyTyped#35572 (comment)
* Change current news path to news-announcments * Update test * Add NewsCarousel and NewsCarouselItem components * Update storybook component * Add CTA * Add query for carousel articles * Add NewsCarousel component to page * Add custom ellipses and custom arrows * Update styles * Move class to module * fix: resolve type error from useRef return See for where the solution came from DefinitelyTyped/DefinitelyTyped#35572 (comment) * test: add article mock to NewsAnnouncements component * fix a11y violation in carousel, update mock in test * Style updates * Add test * Add test * Add news page from main * Add view older internal news link * Add comment * Update styles * Add conditional render for link * Remove unnecessary importants * Update default image * Update tests * Remove flex styles * Add comment Co-authored-by: John Gedeon <john@truss.works> Co-authored-by: Abigail Young <abbyoung@gmail.com>
) * Change current news path to news-announcments * Update test * Add NewsCarousel and NewsCarouselItem components * Update storybook component * Add CTA * Add query for carousel articles * Add NewsCarousel component to page * Add custom ellipses and custom arrows * Update styles * Move class to module * fix: resolve type error from useRef return See for where the solution came from DefinitelyTyped/DefinitelyTyped#35572 (comment) * test: add article mock to NewsAnnouncements component * fix a11y violation in carousel, update mock in test * Style updates * Add test * Add test * Add news page from main * Add view older internal news link * Add comment * Update styles * Add conditional render for link * Update text * Display four latest articles * Update link * Update button text * Update test * Update test * Update page copy * Update RSS query * Update test * Update test * Update classname Co-authored-by: John Gedeon <john@truss.works> Co-authored-by: Abigail Young <abbyoung@gmail.com>
## [4.7.0](4.6.0...4.7.0) (2022-08-24) ### Features * Add internal news carousel for news and announcements page ([#744](#744)) ([c4acfe6](c4acfe6)), closes [/github.com/DefinitelyTyped/DefinitelyTyped/issues/35572#issuecomment-498242139](https://github.com/USSF-ORBIT//github.com/DefinitelyTyped/DefinitelyTyped/issues/35572/issues/issuecomment-498242139) * Display Spaceforce.mil news articles below the news carousel ([#746](#746)) ([e13b57a](e13b57a)), closes [/github.com/DefinitelyTyped/DefinitelyTyped/issues/35572#issuecomment-498242139](https://github.com/USSF-ORBIT//github.com/DefinitelyTyped/DefinitelyTyped/issues/35572/issues/issuecomment-498242139)
Had the same issue. I was using both TypeScript and ESLint with the react/require-default-props rule enabled. To resolve the issue, you can disable the react/require-default-props rule in your ESLint configuration file (.eslintrc or similar). In your ESLint configuration file, add or update the rules section like this: {
"rules": {
"react/require-default-props": "off"
}
} This will disable the react/require-default-props rule, and you shouldn't see the error anymore. Since you are using TypeScript to handle optional props and default values, this rule is not necessary for your project. |
Initializing to null the ref to be compatible with LegacyRef
@types/16.8.17
package and had problems.The text was updated successfully, but these errors were encountered: