简体   繁体   English

为什么 encumbranceByType object 可能未定义?

[英]Why is encumbranceByType object possible undefined?

I have a react component that takes in data of type EncumbranceData[] and restructures that data before mapping through it.我有一个 React 组件,它接收EncumbranceData[]类型的数据并在映射之前重组该数据。 This restructuring involves creating an empty object of type EncumbrancesByType and creating keys and values for it based on encumbranceData此重组涉及创建一个 EncumbrancesByType 类型的空encumbranceData EncumbrancesByType创建键和值

However, I keep getting an "Object possible undefined" error where it says encumbrancesByType[e.type].push(e.suite) .但是,我不断收到“对象可能未定义”错误,其中显示encumbrancesByType[e.type].push(e.suite) I don't understand how this could be undefined, as none of the fields on these types are optional.我不明白这怎么可能是未定义的,因为这些类型的字段都不是可选的。 This component will always receive data of type EncumbranceData that will always have a type, id, and suite.该组件将始终接收EncumbranceData类型的数据,该数据始终具有类型、ID 和套件。 EncumbranceData cannot be undefined. EncumbranceData不能未定义。 The object starts as an empty one, but each iteration through the forEach method should initialize each key with a truthy empty array. object 开始时是一个空数组,但是通过forEach方法的每次迭代都应该使用一个真实的空数组来初始化每个键。

How can the object possible be undefined, then, at the push(e.suite) statement?那么,在push(e.suite)语句中,object 怎么可能是未定义的呢?

I can get it to work by just using a bunch of optional operators ( encumbrancesByType?.push() ), but I feel like that defeats the point of type safety.我可以通过使用一堆可选运算符 ( encumbrancesByType?.push() ) 来让它工作,但我觉得这违背了类型安全的要点。

type EncumbranceData = {
  id: string;
  suite: string;
  type: string;
};

interface EncumbrancesByType {
  [key: string]: string[];
}

type EncumbranceAlertByTypeProps = {
  id: string;
  suites: string[];
  type: string;
};

const EncumbranceAlertByType: React.FC<EncumbranceAlertByTypeProps> = ({ id, suites, type }) => {
  const renderSuites = suites.map((s) => <span>{s}</span>);
  return (
    <div>
      <div>{type}</div>
      {renderSuites}
    </div>
  );
};

type ConflictingEncumbrancesAlertProps = {
  encumbranceData: EncumbranceData[];
  isOpen: boolean;
  onContinue(): void;
  onCancel(): void;
  suiteIdsToCheck: string[];
  encumbranceTypesToConsider?: EncumbranceType[];
};

const ConflictingEncumbrancesAlert: React.FC<ConflictingEncumbrancesAlertProps> = ({
  encumbranceData,
  isOpen,
  onContinue,
  onCancel,
  suiteIdsToCheck,
  encumbranceTypesToConsider,
}) => {

  const encumbrancesByType: EncumbrancesByType = {}
  encumbranceData.forEach((e) => {
    if (!encumbrancesByType[e.type]) encumbrancesByType[e.type] = [e.suite]
    else encumbrancesByType[e.type].push(e.suite)
  })

  const encumbrancesContent = Object.keys(encumbrancesByType).map((type) => (
    <EncumbranceAlertByType suites={encumbrancesByType[type]} type={type} />
  ));

  return <div>{encumbrancesContent}</div>;
};

export default ConflictingEncumbrancesAlert;

You likely have the noUncheckedIndexedAccess rule enable in your tsconfig .您可能在tsconfig中启用了noUncheckedIndexedAccess规则。 When you have this rule the compiler will always complain on unchecked index access.当您有此规则时,编译器将始终抱怨未经检查的索引访问。

Also, TS won't narrow down (remove the undefined ) on index access.此外,TS 不会缩小(删除undefined )索引访问。 In order to have the compiler do that, you'll have to use an intermidiate variable.为了让编译器这样做,你必须使用一个中间变量。

encumbranceData.forEach((e) => {
  const foo = encumbrancesByType[e.type]; // intermediate variable
  if (foo) {
    foo.push(e.suite); // ok 
  }
});

Playgroud 游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM