flowtype: Как получить тип generi c с внутренней функцией? - PullRequest
0 голосов
/ 15 января 2020

Я использую тип потока.
Я предполагаю, что следующие два кода одинаковы, но приведенный выше код выдает ошибку.

В чем разница в следующих двух кодах?
и как использовать generi c T введите в getMergedState аргументы функции без указания типа getMergedState<State>

ошибка: (свойство foo отсутствует в T, но существует в литерале объекта)

type State = {| foo: string, bar: string |}

function getState<T>(initialState: T) {
  const getMergedState = (prevState: T, newState: $Shape<T>): T => ({
    ...prevState,
    ...newState
  });
  return [state, getMergedState];
}
const [state, getMergedState] = getState<State>({ foo: '1', bar: '2' });
const newState = getMergedState(state, { foo: '2' });

работает:

type State = {| foo: string, bar: string |}

function getState<T>(initialState: T) {
  const getMergedState = <K>(prevState: K, newState: $Shape<K>): K => ({
   ...prevState,
   ...newState
  });
  return [state, getMergedState];
}
const [state, getMergedState] = getState<State>({ foo: '1', bar: '2' });
const newState = getMergedState<State>(state, { foo: '2' });

try flow

РЕДАКТИРОВАТЬ:
я упростил код, чтобы показать ссылку потока, но сделал несколько ошибок.

оригинальный код:

function useMergeState<T>(initialState: T) {
  const [state, setState] = React.useState<T>(initialState);
  const setMergedState = (newState: $Shape<T>) =>
    setState((prevState: T) => ({ ...prevState, ...newState }));
  return [state, setMergedState];
}

type State = {|
  text: ?string,
  text2: ?string
|};

const getInitialState = (): State => {
  return {
    text: null,
    text2: null
  };
};

const Example = () => {
  const [state, setState] = useMergeState<State>(getInitialState());
  return (
    <form>
      <input
        value={state.text}
        onChange={event => {
          setState({ text: event.target.value });
        }}
      />
    </form>
  );
};

1 Ответ

0 голосов
/ 16 января 2020

Я получил все для проверки типов со следующим кодом на v0.116.0:

import * as React from "react";

function useMergeState<T: {}>(initialState: T): [T, $Shape<T> => void] {
  const [state, setState] = React.useState<T>(initialState);
  const setMergedState = (newState: $Shape<T>) =>
    setState((prevState: T): T => ({ ...prevState, ...newState }));
  return [state, setMergedState];
}

type State = {|
  text: ?string,
  text2: ?string
|};

const getInitialState = (): State => {
  return {
    text: null,
    text2: null
  };
};

const Example = () => {
  const [state, setState] = useMergeState<State>(getInitialState());
  return (
    <form>
      <input
        value={state.text}
        onChange={event => {
          setState({ text: event.target.value });
        }}
      />
    </form>
  );
};

Попробуйте Flow

Основные изменения были подтипом T как object (T: {}), указав тип возврата useMergeState ([T, $Shape<T> => void]) и указав тип возврата setState в useMergeState (T). (Я также добавил импорт из реакции для Try Flow.) Код выдаст ошибку, если вы вызовете setState со свойствами, которые не отображаются в определении типа State, или если типы значений не подходят (например, вы установили число в качестве значения text).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...