javascript - Typ '{ children: Element; }' nemá žiadne spoločné vlastnosti s typom 'IntrinsicAttributes' - React 18.2.0


Mám otázku. Momentálne sa učím React s TypeScriptom pomocou učebnice - Fullstack React with TypeScript. Práve som pri prvej aplikácii - klone Trella.

Narazil som na chybu, ktorú mám problém vyriešiť.

Dostávam túto chybu z AppStateContext.

Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'

Toto je blok, kde je definované: 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>
  )
}

Toto je blok, kde sa to volá: index.tsx

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
    <AppStateProvider>
      <App />
    </AppStateProvider>
);

Chyba pochádza z miesta, kde volám v súbore index.tsx.

Na pomoc sa skutočne vopred teším. Verzia Reactu je 18.2.0

Odpoveď č. 1

Musíte sa zbaviť explicitného typu FC pre AppStateProvider.

Pozrite si tento zjednodušený príklad:

interface FunctionComponent<P = {}> {
    (props: P, context?: any): ReactElement<any, any> | null;
}

Ako ste si možno všimli, FunctionComponent je zjednodušená verzia (odstránili sa props, ktoré nesúvisia s vašou otázkou) FC.

Generický P predstavuje argument props. Ak generický P nemá vlastnosť children, nesmiete ju používať. V skutočnosti smiete používať iba tie vlastnosti, ktoré sú deklarované v generickom P.

Majte prosím na pamäti, že ste použili iba FC, čo znamená, že generický typ P je nahradený {}. Preto nemáte povolené poskytovať žiadnu vlastnosť komponentu React.

Pozri toto:

type Fn<P = 'no properties'> = (props: P) => void

const fn: Fn = (props) => {
    props // no properties
 }

props má typ 'no properties' a nie je dovolené ho prepísať iným typom:

// errpr
const fn: Fn = (props:number) => {
    props // no properties
 }

Váš príklad je trochu iný, pretože typ TypeScript {} je zložitý typ. Keďže všetko v JavaScripte je objekt, akýkoľvek (nie som si úplne istý na 100%) typ je priraditeľný k {}. Preto nedostanete chybu pri používaní React.PropsWithChildren<{}> pre props. Používanie React.PropsWithChildren<{}> však neovplyvňuje typ AppStateProvider, pretože keď ho zavoláte, bude očakávať iba {} ako vlastnosti.

Len ako pravidlo, máte povolené použiť buď explicitný typ celej funkcie a vyhnúť sa používaniu typu argumentu, alebo jednoducho použiť typ pre argument.

Buď toto:

type Fn<P = 'no properties'> = (props: P) => void

const fn: Fn = (props) => {
    props // no properties
 }

ALEBO

const fn = (props:'no properties') => {
    props // no properties
 }

P.S. V reakcii 17.*, FC mal typ children, pozri tento článok

Odpoveď č. 2

Chyba vám v podstate hovorí, že typ children (ktorý je ELements) nemá žiadne spoločenstvo s vaším typescript definovaným typom (React.PropsWithChildren<{}>). Jednoduchý spôsob, ako problém vyriešiť, je zmeniť AppStateContext.tsx na niečo takéto:

export const AppStateProvider: FC = ({ children }: {children:Elements) => {
...

Avšak, ak naozaj chcete cvičiť čistý kód a používať React.PropsWithChildren, tu je repozitár s ukážkovým prípadom použitia: https://github.com/KishorNaik/Sol_PropsWithChildren_React

Dúfam, že to pomôže