React / Typscript: typehint любой не работает - PullRequest
0 голосов
/ 21 октября 2019

У меня есть очень простой реагирующий компонент с именем: github.tsx

В нем у меня есть этот код:

import React from 'react'
import axios from 'axios'

class Github extends React.Component<{any, any}>{

  state = {
    user: []
  }

  getRepoUser = async () => {
    let res = await axios.get('https://api.github.com/users/example');
    this.setState({
      user: res.data
    })
  }

  componentDidMount () {
   this.getRepoUser()
  }

  render () {
    const { user } = this.state

    return (
      <div>
        <h2>{user.login}</h2>
        <p> repos: {user.public_repos} </p>
        <p>followers: {user.followers}</p>
        <img src={user.avatar_url} alt=""/>
      </div>
    )
  }
}

export default Github

Я подумал, добавив <{any, any}> к компоненту, яне было бы проблем, но я вижу консольные ошибки как это:

backend.js:6 /home/example/tuts/components/github.tsx
./components/github.tsx
[tsl] ERROR in /home/example/tuts/components/github.tsx(35,24)
      TS2339: Property 'avatar_url' does not exist on type 'any[]'.

Я получаю вышеупомянутую ошибку 4 раза, для user.login, user.public_repos, user.followers, user.avatar_url

Ответы [ 4 ]

1 голос
/ 21 октября 2019

Для этого есть несколько причин:

  1. React.Component интерфейс принимает два типа, React.Component<P, S>, где P - тип для реквизита, а S - тип для состояния. Он также может принимать один тип, который будет просто P. Это то, что происходит в вашем случае, вы определяете тип P как объект {any, any} (машинопись должна жаловаться на это, потому что вы указываете дубликат ключа). Это означает, что вы не предоставляете тип для государства. который из DefinetelyTyped должен быть любым .

  2. вы явно определяете state для класса, поэтому машинописный текст отклоняет тип для него из определения. state.user является массивом, поэтому в этом элементе нет avatar_url;

Чтобы исправить это, вы можете явно указать, что state является любым при определении

    state: any = {
        user: []
    }

Лучшим решением было бы на самом деле определить тип или интерфейс для состояния, а не использовать их. any следует избегать, особенно в коде, который вы пишете для своего приложения.

Вы можете определить пользовательский тип или интерфейс:

type User = {
    name: string,
    avatar?: string
}
// or 
interface IUser {
    name: string,
    avatar?: string
}
1 голос
/ 21 октября 2019

Когда вы создаете компонент, первый тип, который вы передаете React.Component, является типом реквизита, а второй определяет тип состояния:

interface IState {}

interface IProps {}

class Component extends React.Component<IProps, IState> {

Когда вы делаете это:

class Github extends React.Component<{any, any}>

Вы определяете тип реквизита компонента только как объект, у которого есть 2 свойства, оба с именем any, которые не будут работать.

Вместо этого тип вашего компонента должен быть таким:

class Github extends React.Component<any, any>

Также выведенный тип state.user является массивом, поскольку начальное состояние:

state = {
  user: []
}

, поэтому вы получаете ошибки о user.login, user.public_repos ...

Вы можете напечатать состояние следующим образом:

interface IState {
  user: User;
}

interface User {
  login: string;
  public_repos: string;
  followers: string;
  avatar_url: string;
}

class Github extends React.Component<any, IState> {
  public state = {
    user: {
      login: "",
      public_repos: "",
      followers: "",
      avatar_url: "",
    },
  };

  public getRepoUser = async () => {
    const res = await axios.get<User>("https://api.github.com/users/example");
    this.setState({
      user: res.data,
    });
  }
  ...
}
1 голос
/ 21 октября 2019

Вы делаете семантическую ошибку. Хотя ваша программа синтаксически допустима, это не означает, что вы, как представляется, намерены.

Критическим моментом является то, что в TypeScript объявления имеют форму

<name> [: type]

То естьимя стоит на первом месте, оно обязательно, всегда обязательно и может сопровождаться аннотацией типа при желании.

Поэтому, если я пишу,

type Props = {
    any
};

Я объявляю тип с помощью свойство с именем any. Вышесказанное эквивалентно

type Props = {
    any: any
};

Поскольку у меня нет аннотации типа и контекста, откуда его выводить.

Кроме того, я пишу,

type Props = {
    any,
    any
};

У меня естьобъявленный член с именем any дважды, ошибка.

Вероятно, вы намеревались указать тип any для параметров типа Props и State, например, так.

class Github extends React.Component<any, any> {

}

Но вместо этого вы указали тип {any, any} для Props и не указали тип для State.

0 голосов
/ 21 октября 2019

«Typehint» в React.Component<{any, any}> не имеет ничего общего с типом состояния, это тип реквизита, который вы указали. Ознакомьтесь с декларацией реагирующего компонента: declare class React$Component<Props, State = void> { ...

...