【问题标题】:@mui/material Autocomplete Typescript error@mui/material 自动完成打字稿错误
【发布时间】:2021-12-01 11:46:22
【问题描述】:

我正在开发一个使用 react-hook-form 的自动完成字段。目前,它似乎按预期工作,但是我收到以下 TS 错误:

Type '{ autoComplete: true; disableClearable: true; fullWidth: true; options: { value: MeasuringSystem; label: string; }[]; onChange: (e: SyntheticEvent<Element, Event>, v: { ...; }) => void; ... 5 more ...; ref: RefCallBack; }' is not assignable to type 'AutocompleteProps<{ value: MeasuringSystem; label: string; }, undefined, true, undefined, "div">'.
  Types of property 'value' are incompatible.
    Type 'string | { value: MeasuringSystem; label: string; }' is not assignable to type '{ value: MeasuringSystem; label: string; } | undefined'.
      Type 'string' is not assignable to type '{ value: MeasuringSystem; label: string; } | undefined'.ts(2322)

以下是相关代码:

export enum MeasuringSystem {
  Imperial = 'IMPERIAL',
  Metric = 'METRIC',
}

interface MeasuringSystemOption {
  value: MeasuringSystem;
  label: string;
}

interface DefaultValues {
  firstName: string | undefined;
  lastName: string | undefined;
  trailName: string | undefined;
  measuringSystem: MeasuringSystemOption;
  address1: string | undefined;
  address2: string | undefined;
  city: string | undefined;
  state: string | undefined;
  country: string | undefined;
}

const measuringSystemOptions = [
  { value: MeasuringSystem.Imperial, label: 'Imperial (lbs, oz)' },
  { value: MeasuringSystem.Metric, label: 'Metric (kg, g)' },
];

const Profile: React.FC = () => {
  ...other code

  const defaultSystem = measuringSystemOptions.find(
    opt => opt.value === currentUser?.measuringSystem
  );
  const {
    control,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm({
    resolver: yupResolver(validationSchema),
    mode: 'onSubmit',
    reValidateMode: 'onBlur',
    defaultValues: {
      firstName: currentUser?.firstName ?? '',
      lastName: currentUser?.lastName ? currentUser.lastName : '',
      measuringSystem: defaultSystem || '',
      address1: currentUser?.address1 ?? '',
      address2: currentUser?.address2 ? currentUser.address2 : '',
      city: currentUser?.city ? currentUser.city : '',
      state: currentUser?.state ? currentUser.state : '',
      country: currentUser?.country ? currentUser.country : '',
    },
  });

  useEffect(() => {
    const resetUser = {
      firstName: currentUser?.firstName ?? '',
      lastName: currentUser?.lastName ?? '',
      address1: currentUser?.address1 ?? '',
      address2: currentUser?.address2 ?? '',
      city: currentUser?.city ?? '',
      state: currentUser?.state ?? '',
      country: currentUser?.country ?? '',
      measuringSystem: defaultSystem ?? '',
    } as any;
    if (currentUser) reset(resetUser);
  }, [currentUser]);

  return (
    <div>
      <Controller
        control={control}
        name="measuringSystem"
        render={({ field }) => (
          <Autocomplete // <-- TS Error
            {...field}
            autoComplete
            disableClearable
            fullWidth
            options={measuringSystemOptions}
            onChange={(e, v) => field.onChange(v)}
            isOptionEqualToValue={(option, value) =>
              option.value === value.value
            }
            renderInput={(params: AutocompleteRenderInputParams) => (
              <TextField
                {...params}
                inputRef={field.ref}
                error={!!errors?.measuringSystem}
                helperText={(errors?.measuringSystem as any)?.message}
                label="Preferred Measuring System"
                variant="outlined"
                size="small"
                InputProps={{
                  ...params.InputProps,
                  startAdornment: (
                    <InputAdornment position="start">
                      <PublicIcon
                        color={
                          errors?.measuringSystem ? 'error' : 'inherit'
                        }
                      />
                    </InputAdornment>
                  ),
                }}
              />
            )}
          />
        )}
      />  
    </div>
  );
};

我了解了错误的全部内容,但我只是不确定如何实际解决这个问题?

【问题讨论】:

  • MeasuringSystem的类型是什么?你能重现here中的错误吗?
  • @NearHuscarl 我用顶部定义的枚举更新了帖子。我还尝试在代码沙箱here 中复制它,但我在isOptionEqualToValue 属性中收到不同的错误。
  • 您可以像这样在表单中键入值:useForm&lt;FormInputs&gt;。见thiscodesandbox。
  • 啊,没想到我能做到!我最终使用DefaultValues 类型定义传递给useForm,并将defaultValue 更改为measuringSystem: defaultSystem,这似乎已经修复了错误。非常感谢!

标签: typescript material-ui react-hook-form


【解决方案1】:

感谢@NearHuscarl 在帖子 cmets 中的修复。这是修复它的原因:

const {
    control,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm<DefaultValues>({
    resolver: yupResolver(validationSchema),
    mode: 'onSubmit',
    reValidateMode: 'onBlur',
    defaultValues: {
      firstName: currentUser?.firstName ?? '',
      lastName: currentUser?.lastName ?? '',
      trailName: currentUser?.trailName ?? '',
      measuringSystem: defaultSystem,
      address1: currentUser?.address1 ?? '',
      address2: currentUser?.address2 ?? '',
      city: currentUser?.city ?? '',
      state: currentUser?.state ?? '',
      country: currentUser?.country ?? '',
    },
  });

我将&lt;DefaultValues&gt; 传递给useForm 定义,然后更改measuringSystem,以便在未定义或为空时它不会设置为空字符串。修复所有问题!

【讨论】:

    猜你喜欢
    • 2019-10-21
    • 2018-06-23
    • 1970-01-01
    • 2020-04-15
    • 2022-08-23
    • 1970-01-01
    • 2023-04-05
    • 2019-06-27
    • 2021-12-17
    相关资源
    最近更新 更多