Машинопись и хуки - PullRequest
       29

Машинопись и хуки

1 голос
/ 14 июня 2019

Может кто-нибудь посоветовать мне лучший способ конвертировать этот хук в безопасную версию, используя Typescript, пожалуйста. Это простой переключатель для отображения другой «вещи» в состоянии переключения.

useToggle.js

const useToggleButton = ({on,off}) => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle? on : off}
    </div>
  )
  return [ToggleButton, toggle, setToggle]
}

Дело в том, что он возвращает массив с компонентом, состоянием и функцией setState. Моя попытка ниже, но я получаю ошибки

TS2605: JSX element type 'IReturnType' is not a constructor function for JSX elements.   Type 'IReturnType' is missing the
following properties from type 'Element': type, props, key

TS2739: Type '(boolean | Dispatch<SetStateAction<boolean>>)[]' is
missing the following properties from type 'IReturnType': component,
state, func

useToggle.tsx

import * as React from 'react'

interface IToggleBntProps {
  on: any
  off: any
}

interface IState {
  bol: boolean
}

interface IReturnType {
  component: React.FunctionComponent
  state: boolean
  func: (bol: boolean) => IState
}

const useToggleButton = ({ on, off }: IToggleBntProps): IReturnType => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle ? on : off}
    </div>
  )
  return [ToggleButton, toggle, setToggle]
}

export default useToggleButton

1 Ответ

1 голос
/ 14 июня 2019

TypeScript может автоматически определить большинство этих типов автоматически!

В приведенном ниже коде выражение as const ( постоянное утверждение ) в конце вашего оператора возврата позволяет TypeScript правильно вывести желаемый тип возвращаемого значения: [() => JSX.Element, boolean, React.Dispatch<React.SetStateAction<boolean>>].

Если вы хотите быть явным, вы можете сделать type IReturnType = [() => JSX.Element, boolean, React.Dispatch<React.SetStateAction<boolean>>], но это многословно и не нужно.

interface IToggleBntProps {
  on: any
  off: any
}

const useToggleButton = ({ on, off }: IToggleBntProps) => {
  const [toggle, setToggle] = React.useState(false)

  const ToggleButton = () => (
    <div
      role="button"
      onClick={() => setToggle(!toggle)}
      data-testid="portal-toggle-btn"
    >
      {toggle ? on : off}
    </div>
  )

  // saying 'as const' here means that TypeScript automatically
  // knows that this should be a tuple type of three elements.
  // Not you need TypeScript 3.4 or newer 
  return [ToggleButton, toggle, setToggle] as const;
}

export default useToggleButton
...