Material UI自动完成上的Typescript Equality问题

Posted

技术标签:

【中文标题】Material UI自动完成上的Typescript Equality问题【英文标题】:Typescript Equality issue on Material UI Autocomplete 【发布时间】:2020-08-13 17:12:51 【问题描述】:

数据存储为:

  iso: "gb", label: "United Kingdom", country: "United Kingdom" ,
  iso: "fr", label: "France", country: "France" 

传递给自动完成的值是:

 iso: "gb", label: "United Kingdom", country: "United Kingdom" 

控制台报错

Material-UI:提供给 Autocomplete 的值无效。 没有一个选项与@​​987654326@ 匹配。

value= 报告类型错误

键入'字符串 | ICountry 不可分配给类型 'ICountry |国家[] |空 |不明确的'。 类型“字符串”不可分配给类型“ICountry |国家[] |空 |未定义'。

问题:将数据传递给组件并没有将其设置为相应的选项,我完全不知道如何解决这个问题。

问题的代码框: https://codesandbox.io/s/charming-firefly-zl3qd?file=/src/App.tsx

import * as React from "react";
import  Box, Typography, TextField, Button  from "@material-ui/core";
import  Autocomplete  from "@material-ui/lab";
import "./styles.css";
import  countries  from "./countries";
import  investors  from "./investor";
import  Formik  from "formik";

interface ICountry 
  iso: string;
  country: string;
  label: string;


const isoToFlag = (isoCode: string) => 
  if (isoCode) 
    return typeof String.fromCodePoint !== "undefined"
      ? isoCode
          .toUpperCase()
          .replace(/./g, char =>
            String.fromCodePoint(char.charCodeAt(0) + 127397)
          )
      : isoCode;
  
  return "";
;

const App: React.FC = () => 
  const investor = investors.find(element => element.id === "123");


  return (
    <div className="App">
      <Formik
        initialValues=
          address: 
            country: investor?.legal.address.country ? investor.legal.address.country : '',
          
        
        onSubmit=(values, actions) => 
          console.log( values, actions );
          actions.setSubmitting(false);
        
      >
        ( submitForm, isSubmitting, values, setFieldValue, setValues ) => 

          return (
            <form>

              <Autocomplete
                id="country"
                options=countries
                getOptionLabel=option => option.label
                value=values.address.country
                renderOption=(option: ICountry) => (
                  <Box display="flex" flexDirection="row" alignItems="center">
                    <Box mr=1>isoToFlag(option.iso)</Box>
                    <Box>
                      <Typography variant="body2">option.label</Typography>
                    </Box>
                  </Box>
                )
                onChange=(e: object, value: any | null) => 
                  console.log('do the types match?', typeof value === typeof values.address.country);
                  console.log('do the objects match?', value === values.address.country);
                  console.log('the objects in question', value, values.address.country);
                  console.log("                  ");
                  setFieldValue("address.country", value);
                
                renderInput=params => (
                  <TextField
                    ...params
                    name="address.country"
                    label="Country"
                    variant="outlined"
                    fullWidth
                  />
                )
              />
              <Button
                variant="contained"
                size="large"
                color="primary"
                disabled=isSubmitting
                onClick=submitForm
              >
                Submit
              </Button>
            </form>
          );
        
      </Formik>
    </div>
  );
;

export default App;

countries.ts


import  ICountry  from "./investor";

export const countries: ICountry[] = [
  
    iso: "gb",
    label: "United Kingdom",
    country: "United Kingdom"
  ,
  
    iso: "fr",
    label: "France",
    country: "France"
  
];

【问题讨论】:

很高兴您有一个代码框链接,但您应该在问题本身中包含所有相关代码作为文本(请参阅How to Ask)。我对material-ui一无所知,但type问题似乎是您将初始值设置为可能''string,而不是undefined,如this。运行时问题可能是其他问题。 感谢 Jcalz,我将把您的观点记入未来的问题中。 【参考方案1】:

来自Material-UI的完整消息是:

Material-UI:提供给 Autocomplete 的值无效。 没有一个选项与@​​987654323@ 匹配。 您可以使用 getOptionSelected 属性自定义相等测试。

默认的相等测试只是===,所以如果你的选项是对象,你的值必须是那些精确的对象之一才能匹配。具有相同值的不同对象将不匹配。

但正如消息告诉您的那样,您可以通过 getOptionSelected 属性自定义相等测试。例如,您可以指定:

getOptionSelected=(option, value) => option.iso === value.iso

或者您可以对所有对象属性进行深度相等性检查。

类型错误可以用value=values.address.country as ICountry修复。

这是您的沙盒的工作版本:https://codesandbox.io/s/autocomplete-getoptionselected-b6n3s

【讨论】:

对我有用!!清除此警告“Material-UI:提供给自动完成的值无效。没有任何选项匹配”。谢谢。 最新 Material UI 实验室依赖项 (4.0.0-alpha.57) 的错误相同。似乎无法修复。谁想避免警告,请降级到 4.0.0-alpha.51(如 Codesandbox 示例中所用)。该版本删除了对我的警告。 为我工作。谢谢。

以上是关于Material UI自动完成上的Typescript Equality问题的主要内容,如果未能解决你的问题,请参考以下文章

Material-ui 自动完成过滤列表

如何更改 Material ui 自动完成中选项的字体大小?

自动完成中的 React Material UI 打开模式失去焦点

Material UI 自动完成不同的颜色标签?

Material UI - 自动完成样式

移除 React Material ui 组件中自动完成的下划线样式