«Не удается вызвать выражение, тип которого не имеет подписи вызова» в Typescript? - PullRequest
0 голосов
/ 10 мая 2019

У меня есть React-Final-Form, которую я хочу напечатать своими собственными типами. Но `children (renderRest) 'выдает следующую ошибку:

Невозможно вызвать выражение, тип которого не имеет подписи вызова. Тип 'строка | номер | правда | {} | ReactElement ReactElement Компонент)> | ноль) | (новый (реквизит: любой) => Компонент)> | ReactNodeArray | ReactPortal | ((реквизит: FormRenderProps) => ReactNode) 'нет совместимого вызова signatures.ts (2349)

И мой код:

import React from "react";
import styled from "styled-components";
import { Form as StateForm, FormProps } from "react-final-form";

import Box from "src/App/Components/Layout/Box";

const StyledForm = styled(Box)``;

const Form = ({ children, ...rest }: FormProps) => {
  return (
    <StateForm
      {...rest}
      render={({ handleSubmit, ...renderRest }) => (
        <StyledForm as="form" onSubmit={handleSubmit}>
          {children && children(renderRest)}
        </StyledForm>
      )}
    />
  );
};

export default React.memo(Form);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Эта ошибка «Невозможно вызвать выражение, тип которого не имеет подписи вызова», возникала в различных ситуациях, которые мне удалось решить. Но не в этом случае, к сожалению.

Любые подсказки, пожалуйста? Спасибо

1 Ответ

1 голос
/ 10 мая 2019

В определениях типа для react-final-form он определяет children в RenderableProps (который расширяется FormProps) как:

export interface RenderableProps<T> {
  children?: ((props: T) => React.ReactNode) | React.ReactNode;
  component?: React.ComponentType<T> | string;
  render?: (props: T) => React.ReactNode;
}

Так что children - это либо функция, которая принимает props и создает React.ReactNode, либо это экземпляр React.ReactNode напрямую. В последнем случае вы не можете использовать его как функцию. Поскольку это может быть любой из них, TS позволит вам делать то, что является общим между ними. Ошибка Cannot invoke an expression whose type lacks a call signature. в основном говорит: «Вы пытаетесь использовать children, как будто это функция, и это недопустимо, потому что я точно не знаю, является ли она функцией».

Я не знаю библиотеку react-final-form достаточно хорошо, чтобы сказать, как лучше всего это исправить. Вы могли бы разыграть ...

(children as ((props: T) => React.ReactNode))(renderRest);

... или вы можете добавить охрану типа ...

if (typeof children === 'function') {
  children(renderRest);
}
...