Ошибка TypeScript: не удается вызвать выражение, тип которого не имеет подписи вызова - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь создать реагирующий повторно используемый компонент: таблицу, которая должна быть либо списком команд, либо списком игр.Следовательно, запрос GraphQL отличается в зависимости от того, что получено.

поэтому у меня есть эти интерфейсы и типы:

export interface Team {
  id: string;
  name: string;
}

export interface Game {
  id: string;
  competition: string;
}

export interface Data {
  allElems?: Team[] | Game[]
  [elements: string]: Team[] | Game[] | undefined
}

Мой компонент выглядит так:

interface SectionTableProps {
  query: object
}

class SectionTableQuery extends Query<Data, {}> {}

class SectionTable extends React.Component<SectionTableProps, {}> {
  constructor(props: SectionTableProps) {
    super(props);
  }
  render() {
    return (
          <SectionTableQuery query={this.props.query}>
          {({ data = {}, error, loading }) => {
            if (loading) {
              return <tbody><tr><td>LOADING</td></tr></tbody>
            };
            if (error !== undefined) {
              return <tbody><tr><td>ERROR</td></tr></tbody>
            };
            return (
              <tbody>
                {Object.keys(data).map(elements => {
                  data[elements].map(
                    elem => (
                    <tr key={elem.id} >
                      <th scope="row">{elem.id}</th>
                      {Object.keys(elem).map(k => {
                        if (k !== "id" && k !== "__typename") {
                          return <td key={elem[k]}>{elem[k]}</td>
                        }
                      })}
                    </tr>
                )
              )
            }
          )
          }
              </tbody>
            );
          }}
        </SectionTableQuery>
    )
  }
}

, но я получаю следующую ошибку:

TypeScript error: Cannot invoke an expression whose type lacks a call signature. Type '(<U>(callbackfn: (value: Team, index: number, array: Team[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: Game, index: number, array: Game[]) => U, thisArg?: any) => U[])' has no compatible call signatures.  TS2349

    42 |               <tbody>
    43 |                 {Object.keys(data).map(elements => {
  > 44 |                   (data[elements] || []).map(
       |                   ^
    45 |                     elem => (
    46 |                     <tr key={elem.id}>
    47 |                       <th scope="row">{elem.id}</th>

почему это так?Я действительно не знаю, почему Game и Team не совместимы ...

1 Ответ

1 голос
/ 23 апреля 2019

только что нашел решение;не знаю, будет ли это лучше всего:

В моем случае я должен использовать объявление слияния :

Я не могу написать

export interface Team {
  id: string;
  name: string;
}

export interface Game {
  id: string;
  competition: string;
}

export interface Data {
  allElems?: Team[] | Game[]
  [elements: string]: Team[] | Game[] | undefined
}

, поскольку я получу ошибку, упомянутую в моем первоначальном посте.Вместо этого я должен объявить свои интерфейсы следующим образом:

//team
interface Elem {
  id: string;
  name?: string;
  [attr: string]: string | number  | undefined
}

//game
interface Elem {
  id: string;
  homeTeamScore?: number
  competition?: string
  round?: string
}

export interface Data {
  elem?: Elem
  [elements: string]: Elem | undefined
}

На самом базовом уровне объединение механически объединяет элементы обоих объявлений в один интерфейс с одинаковым именем.

...