typescript 为什么可能未定义encranceByType对象?

egdjgwm8  于 2023-01-21  发布在  TypeScript
关注(0)|答案(1)|浏览(156)

我有一个react组件,它接收EncumbranceData[]类型的数据,并在Map之前重新构造该数据,这个重新构造涉及创建EncumbrancesByType类型的空对象,并基于encumbranceData为它创建键和值
但是,我一直收到一个“Object possible undefined”错误,它说encumbrancesByType[e.type].push(e.suite)。我不明白这怎么可能是未定义的,因为这些类型上的字段都不是可选的。这个组件将始终接收类型为EncumbranceData的数据,该数据将始终具有类型、id和suite。EncumbranceData不能是未定义的。该对象开始时为空,但是通过forEach方法的每次迭代都应该用真实的空数组初始化每个键。
那么,在push(e.suite)语句中,对象怎么可能未定义呢?
我可以通过使用一组可选操作符(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;
wz3gfoph

wz3gfoph1#

您可能在tsconfig中启用了noUncheckedIndexedAccess规则。当您启用此规则时,编译器将始终报告未检查的索引访问。
同样,TS不会缩小索引访问范围(删除undefined)。为了让编译器做到这一点,你必须使用一个中间变量。

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

Playground

相关问题