Typescript + React / Redux: Właściwość „XXX” nie istnieje w typie „IntrinsicAttributes & IntrinsicClassAttributes”

91

Pracuję nad projektem z Typescript, React i Redux (wszystkie działające w Electron) i napotykam problem, gdy włączam jeden komponent oparty na klasie do drugiego i próbuję przekazać parametry między nimi. Mówiąc luźniej, mam następującą strukturę komponentu kontenera:

class ContainerComponent extends React.Component<any,any> {
  ..
  render() {
    const { propToPass } = this.props;
    ...
    <ChildComponent propToPass={propToPass} />
    ...
  }
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ContainerComponent);

I składnik podrzędny:

interface IChildComponentProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps, any> {
  ...
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);

Oczywiście uwzględniam tylko podstawy i obie te klasy zawierają znacznie więcej, ale nadal pojawia się błąd, gdy próbuję uruchomić coś, co wygląda na prawidłowy kod. Dokładny błąd, który otrzymuję:

TS2339: Property 'propToPass' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState>> & Readonly<{ childr...'.

Kiedy pierwszy raz napotkałem błąd, pomyślałem, że to dlatego, że nie przekazałem interfejsu definiującego moje rekwizyty, ale stworzyłem go (jak widać powyżej) i nadal nie działa. Zastanawiam się, czy czegoś mi brakuje?

Kiedy wykluczam właściwość ChildComponent z kodu w ContainerComponent, renderuje się dobrze (poza tym, że mój ChildComponent nie ma krytycznej właściwości), ale wraz z nim w JSX Typescript odmawia jego kompilacji. Myślę, że może to mieć coś wspólnego z zawijaniem połączeń na podstawie tego artykułu , ale problemy w tym artykule wystąpiły w pliku index.tsx i były problemem z dostawcą, a moje problemy pojawiają się gdzie indziej.

Protagonista
źródło

Odpowiedzi:

54

Więc po przeczytaniu kilku powiązanych odpowiedzi (szczególnie tej i tej i spojrzeniu na odpowiedź @ basarat na pytanie, udało mi się znaleźć coś, co działa dla mnie. Wygląda (dla moich stosunkowo nowych oczu Reacta), jakby Connect nie dostarczał jawny interfejs do komponentu kontenera, więc został zdezorientowany przez właściwość, którą próbował przekazać.

Więc komponent kontenera pozostał taki sam, ale komponent potomny trochę się zmienił:

interface IChildComponentProps extends React.Props<any> {
  ... (other props needed by component)
}

interface PassedProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps & PassedProps, any> {
  ...
}

....
export default connect<{}, {}, PassedProps>(mapStateToProps, mapDispatchToProps)    (ChildComponent);

Powyższe zadziałało na mnie. Wydawało się, że jawne przekazanie właściwości, których składnik oczekuje od kontenera, działa i oba komponenty są renderowane poprawnie.

UWAGA: Wiem, że to bardzo uproszczona odpowiedź i nie jestem do końca pewien, DLACZEGO to działa, więc jeśli bardziej doświadczony ninja React chce podzielić się wiedzą na temat tej odpowiedzi, z przyjemnością ją poprawię.

Protagonista
źródło
7
Ale React.Propszostał wycofany !!
Sunil Sharma
-1

Zamiast tego export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);wybierz connectdekorator https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/app/fileTree.tsx#L136-L146

@connect((state: StoreState): Props => {
    return {
        filePaths: state.filePaths,
        filePathsCompleted: state.filePathsCompleted,
        rootDir: state.rootDir,
        activeProjectFilePathTruthTable: state.activeProjectFilePathTruthTable,
        fileTreeShown: state.fileTreeShown,
    };
})

Gdzie connect jest zdefiniowane tutaj https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/typings/react-redux/react-redux.d.ts#L6-L36

Czemu?

Wygląda na to, że definicje, których używasz, są prawdopodobnie nieaktualne lub nieprawidłowe (być może są słabo utworzone).

basarat
źródło
2
Wygląda na to, że problemem było połączenie na komponencie podrzędnym, ale znalazłem sposób, aby rozwiązać problem bez zmiany używanych przeze mnie typów. Korzystając z rozwiązania w tym linku , udało mi się zmienić moje połączenie na: connect<{}, {}, PassedProps> Gdzie PassedProps to właściwość, którą komponent pobiera z kontenera nadrzędnego.
Protagonista