Защита для неопределенного типа объединения не работает - PullRequest
1 голос
/ 02 мая 2020

Я получаю следующую ошибку для приведенного ниже кода, который, как я подозреваю, может не соответствовать ожидаемому поведению. В основном TS жалуется, что rules[name] может не вызываться, что верно, потому что это может быть undefined, но если я настороже, в этом случае он все равно выдаст ту же ошибку. Я думаю, что проблема становится ясной после прочтения комментариев в коде.

This expression is not callable.
  Not all constituents of type '((value: string | number) => boolean) | undefined' are callable.
    Type 'undefined' has no call signatures.ts(2349)
type FieldValues = Record<string, string | number>;
type FieldName<FormValues> = keyof FormValues;
type FormState<FormValues> = {
  values: FormValues,
  errors: Record<FieldName<FormValues>, boolean>,
  focused: Record<FieldName<FormValues>, boolean>,
  touched: Record<FieldName<FormValues>, boolean>,
  dirty: Record<FieldName<FormValues>, boolean>,
  isValid: boolean,
  isDirty: boolean,
};

export function useForm<FormValues extends FieldValues> (
  defaultValues: FormValues,
  rules?: Partial<Record<FieldName<FormValues>, (value: string | number) => boolean>>,
) {
...

  const validate = (name: FieldName<FormValues>, value: string | number) => {

    // either "if (rules && rules[names])" or "if (rules && rules[name] instanceof Function)" 
    // should narrow out undefined thus guaranteeing the correct call signature
    if (rules && rules[name] instanceof Function) {
      setFormState((prevFormState: FormState<FormValues>) => ({
        ...prevFormState,
        errors: {
          ...prevFormState.errors,
          [name]: rules[name](value),
        },
        isValid: isFormValid({
          ...prevFormState.errors,
          [name]: rules[name](value),
        }),
      }))
    }
  }

...
}

Я обнаружил, что, по моему мнению, похожая проблема, о которой сообщалось как об ошибке:

проблема stackoverflow

проблема в репозитории Typescript

Но я не могу понять это: i) относится ли это к тому же типу проблемы и ii ) какой обходной путь для этого?

Изменить: изменил заголовок с «Защита для функция в типе объединения не работает» на «Защита для undefined в типе объединения не работает », поскольку он более точно описывает проблему.

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Если я не вижу здесь чего-нибудь, разве не сработает простое условие, такое как rules && rules[name]? Компилятор Typescript уже знает, что это либо функция, либо неопределенная функция, поэтому, если вы проверите, что это truey , этого должно быть достаточно.

0 голосов
/ 03 мая 2020

Для тех, кто сталкивается с подобной проблемой, хорошее объяснение того, почему у TS есть проблемы с ними, и решение для них предоставлено здесь .

Итак, в итоге я сделал:

   if (rules) {
      const fieldRule = rules[name]

      if (fieldRule) {
        setFormState((prevFormState: FormState<FormValues>) => ({
          ...prevFormState,
          errors: {
            ...prevFormState.errors,
            [name]: fieldRule(value),
          },
          isValid: isFormValid({
            ...prevFormState.errors,
            [name]: fieldRule(value),
          }),
        }))
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...