I have a question. I am currently learning react with Typescript using the - fullstack react with typescript textbook. I am now on the first app - the trello clone.
I hit a bug I am finding difficult to resolve.
I get this error from the AppStateContext.
Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'
This is the block where it is defined: AppStateContext.tsx
export const AppStateProvider: FC = ({ children }: React.PropsWithChildren<{}>) => {
const [state, dispatch] = useImmerReducer(appStateReducer, appData)
const { lists } = state
const getTasksByListId = (id: string) => {
return lists.find((list) => list.id === id)?.tasks || []
}
return (
<AppStateContext.Provider value={{ lists, getTasksByListId, dispatch }}>
{children}
</AppStateContext.Provider>
)
}
This is the block where it is called: index.tsx
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<AppStateProvider>
<App />
</AppStateProvider>
);
The error is coming from where I call the in the index.tsx file.
I really appreciate the help in advance. React version is 18.2.0
CodePudding user response:
You need to get rid of explicit FC
type for AppStateProvider
.
See this simplified example:
interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
}
As you might have noticed, FunctionComponent
is a simplified version (removed props which are not related to your question) of FC
.
Generic P
represents props
argument. If P
generic don't have children
property, you are not allowed to use it. In fact you are allowed to use only that properties which are declared in P
generic.
Please keep in mind, that you have used just FC
, it means that P
generic is replaced with {}
. Hence, you are not allowed to provide any property to react component.
See this:
type Fn<P = 'no properties'> = (props: P) => void
const fn: Fn = (props) => {
props // no properties
}
props
has 'no properties'
type, and you are not allowed to override this with another type:
// errpr
const fn: Fn = (props:number) => {
props // no properties
}
YOur example is a bit different, because typescript type {}
is a tricky type. Since everything in javascript is object, any (not sure for 100%) type is assignable to {}
. This is why you don't have an error using React.PropsWithChildren<{}>
for props. However, using React.PropsWithChildren<{}>
does not affect AppStateProvider
type, because when you call it, it will expect only {}
as a properties.
Just as a rule of thumb, you are allowed to use either explicit type of whole function and avoid using argument type or just use type for argument.
Either this:
type Fn<P = 'no properties'> = (props: P) => void
const fn: Fn = (props) => {
props // no properties
}
OR
const fn = (props:'no properties') => {
props // no properties
}
P.S. In react 17.*, FC
had children type
, see this article
CodePudding user response:
The error is basically telling you that the type of children (which is ELements) has no overlap with your typescript defined type (React.PropsWithChildren<{}>). The easy way to fix the issue is to change the AppStateContext.tsx to something like this:
export const AppStateProvider: FC = ({ children }: {children:Elements) => {
...
However, if you really want to practice the clean code, and use React.PropsWithChildren, here is a repository with a sample use case: https://github.com/KishorNaik/Sol_PropsWithChildren_React
HTH