简体   繁体   English

作为 prop 传入的 function 的 React 组件抛出 TypeScript 错误

[英]React component throwing TypeScript error for function passed in as prop

I have a Class based React Component that accepts a function as a prop.我有一个基于 Class 的 React 组件,它接受 function 作为道具。

The component was originally a stateless functional component that accepted the same function without any TypeScript errors.该组件最初是一个无状态功能组件,它接受相同的 function 而没有任何 TypeScript 错误。

Now that I've converted it to a class component I'm getting an error when I call the function: Property 'onRouteChange' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'现在我已经将它转换为 class 组件,当我调用 function 时出现错误: Property 'onRouteChange' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>' Property 'onRouteChange' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'

As well as an error when I de-structure it in the props: Property 'onRouteChange' is missing in type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>' but required in type '{ onRouteChange: any; }'.以及当我在 props 中对其进行解构时出现的错误: Property 'onRouteChange' is missing in type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>' but required in type '{ onRouteChange: any; }'. Property 'onRouteChange' is missing in type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>' but required in type '{ onRouteChange: any; }'.

I initially tried to define it in the types declaration at the top of the file but that's not working either.我最初尝试在文件顶部的类型声明中定义它,但这也不起作用。

Component

type SignInState = {
  signInEmail: string,
  signInPassword: string
}

class SignIn extends Component<{}, SignInState> {
  constructor(props: {}){
    super(props);
    this.state = {
      signInEmail: '',
      signInPassword: ''
    }
  }

  onEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      this.setState({ signInEmail: e.target.value })
  }

  onPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    this.setState({ signInPassword: e.target.value })
  }

  onSubmitSignIn = () => {
    // fetch()
    console.log(this.state);
// TS Error: Property 'onRouteChange' does not exist
    this.props.onRouteChange('home');
  }
  
  render() {
// TS Error: Property 'onRouteChange' is missing in type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>' 
    const { onRouteChange } : { onRouteChange: any} = this.props

    return (
      <Container>
        <Main>
          <Form>
            <Fieldset>
              <SignInTitle>Sign In</SignInTitle>
              <EmailAddressSection>
                <Label>Email</Label>
                <EmailInput />
              </EmailAddressSection>
              <PasswordSection>
                <Label>Password</Label>
                <PasswordInput />
              </PasswordSection>
            </Fieldset>
            <div>
              <SignInButton
                onClick={this.onSubmitSignIn}
                type="submit"
                value="Sign in"
              />
            </div>
            <AccountOptionsSection>
              <AccountOption onClick={() => onRouteChange("register")}>
                Register
              </AccountOption>
            </AccountOptionsSection>
          </Form>
        </Main>
      </Container>
    );
  }
};

export default SignIn;
class SignIn extends Component<{}, SignInState> 

The first param to Component type is props type, and you have not defined it, therefore the error. Component 类型的第一个参数是 props 类型,你没有定义它,因此错误。

Define a interface,定义一个接口,

interface ISignInProp {

onRouteChange:any
}

and pass it to your Component并将其传递给您的组件

class SignIn extends Component<ISignInProp , SignInState> 

Create a type or an interface for your props just as you did with your state.为您的道具创建一个typeinterface ,就像您对 state 所做的那样。

Props Interface道具界面

// interface over type literal
interface IProps { 
 onRouteChange: (param: string) => void
}

Avoid Typing to any避免键入any

Try to avoid typing something to any .尽量避免向any键入内容。 You are basically telling typescript this has no type.您基本上是在告诉 typescript 这没有类型。 That defeats the purpose of TS.这违背了 TS 的目的。 If you truly do not know, type it to unknown .如果您确实不知道,请输入unknown

But, you are passing a string home so you have some information on it that you can use to type it a little better.但是,您正在传递一个string回家,所以您有一些关于它的信息可以用来更好地输入它。

Here, I am guessing onRouteChange is a function that accepts one parameter of type string and returns nothing (does a side effect).在这里,我猜测onRouteChange是一个 function,它接受一个字符串类型的参数并且不返回任何内容(产生副作用)。 You can update this accordingly.您可以相应地更新它。

Typing Your Component Props输入你的组件道具

You do exactly what you did with your state type (prefer interface over types).您所做的与您对 state 类型所做的完全相同(更喜欢接口而不是类型)。

class SignIn extends Component<IProps, IState>

Now you should not have to type onRouteChange when you destructure it.现在,您不必在解构它时键入onRouteChange

const { onRouteChange } : { onRouteChange: any} = this.props

becomes成为

const { onRouteChange } = this.props

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM