javascript - Hur man sätter typ för funktionsegenskaper för dess barn i Typescript? Egenskapen 'children' finns inte på typen TS2339
Som referens använder jag React 16.9.0 och Typescript 3.5.3. Om du installerar Create React App och skapar ett Typescript-projekt kan du lägga till följande minimala exempel för att återskapa problemet:
import React from 'react';
import './App.css';
interface TreeComponentProps {
recursion_level: number;
}
interface TreeComponentState {
}
class TreeComponent extends React.Component<TreeComponentProps, TreeComponentState>
{
constructor(props: TreeComponentProps) {
super(props);
this.state = {
};
}
render() {
console.log( 'I was triggered during TreeComponent render...' );
// const ListElements: any = (props: any) =>
const ListElements: React.FunctionComponent<TreeComponentProps> = (props: TreeComponentProps) =>
{
if( props.recursion_level > 1 )
{
return (
<ol>
{props.children}
</ol>
);
}
else {
return (
<React.Fragment>
{props.children}
</React.Fragment>
);
}
}
if( this.props.recursion_level > 3 ) {
return <div> End recursion on {this.props.recursion_level}... </div>
}
return (
<ListElements>
<div> recursion_level {this.props.recursion_level + 1} <br /> </div>
<TreeComponent key={0} recursion_level={ this.props.recursion_level + 1 }/>
</ListElements>
)
}
}
interface AppProps {
}
interface AppState {
}
class App extends React.Component<AppProps, AppState>
{
private recursion_level: number;
constructor(props: AppProps) {
super(props);
this.recursion_level = 0;
this.state = {
};
}
render() {
console.log( 'I was triggered during App render:', this.state )
return (
<TreeComponent key={0} recursion_level={ this.recursion_level }/>
)
}
}
export default App;
-->
Property 'children' does not exist on type 'TreeComponentProps'. TS2339
27 | return (
28 | <ol>
> 29 | {props.children}
| ^
30 | </ol>
31 | );
32 | }
Om jag ersätter raden:
const ListElements: React.FunctionComponent<TreeComponentProps> = (props: TreeComponentProps) =>
// -->
const ListElements: any = (props: any) =>
Då fungerar allt fint och sidan genereras korrekt:
recursion_level 1
recursion_level 2
recursion_level 3
recursion_level 4
End recursion on 4...
Jag har redan forskat och enligt denna fråga Hur använder man children med React Stateless Functional Component i TypeScript? är detta den korrekta syntaxen:
Sedan React 16.8 är namnen
React.SFCochReact.StatelessComponentföråldrade. Faktiskt har de blivit alias för typenReact.FunctionComponentellerReact.FCför kort.Du skulle använda dem på samma sätt ändå:
const MyStatelessComponent : React.FunctionComponent<MyProps> = props => <div> <p>{props.propInMyProps}</p> <p>{props.children}</p> </div>
Hur kan jag korrekt ställa in typen för mina interna funktionsprops i TypeScript utan att behöva använda any överallt?
Svar #1
Du behöver inte uttryckligen deklarera typen av MyStatelessComponent eftersom den kan härledas.
Eftersom du inte använder children i din andra TreeComponent-deklaration måste du markera children som valfri för att ta bort typefel.
Du saknar också prop recursion_level={this.props.recursion_level} till din ListElements-komponent
import React from 'react';
import './App.css';
interface TreeComponentProps {
recursion_level: number;
children?:React.ReactNode
}
interface TreeComponentState {
}
class TreeComponent extends React.Component<TreeComponentProps, TreeComponentState>
{
constructor(props: TreeComponentProps) {
super(props);
this.state = {
};
}
render() {
console.log( 'I was triggered during TreeComponent render...' );
// const ListElements: any = (props: any) =>
const ListElements = (props: TreeComponentProps) =>
{
if( props.recursion_level > 1 )
{
return (
<ol>
{props.children}
</ol>
);
}
else {
return (
<React.Fragment>
{props.children}
</React.Fragment>
);
}
}
if( this.props.recursion_level > 3 ) {
return <div> End recursion on {this.props.recursion_level}... </div>
}
return (
<ListElements recursion_level={this.props.recursion_level}>
<div> recursion_level {this.props.recursion_level + 1} <br /> </div>
<TreeComponent key={0} recursion_level={ this.props.recursion_level + 1 }/>
</ListElements>
)
}
}
interface AppProps {
}
interface AppState {
}
class App extends React.Component<AppProps, AppState>
{
private recursion_level: number;
constructor(props: AppProps) {
super(props);
this.recursion_level = 0;
this.state = {
};
}
render() {
console.log( 'I was triggered during App render:', this.state )
return (
<TreeComponent key={0} recursion_level={ this.recursion_level }/>
)
}
}
export default App;
