Home > database >  Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttribu
Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttribu

Time:09-01

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.

enter image description here

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

  • Related