reactjs props.items(Object)在返回提前条件后可能未定义

gajydyqb  于 2023-01-12  发布在  React
关注(0)|答案(1)|浏览(113)

我见过一些类似的问题,但没有一个有同样的问题。
我对可能是TypeScript未定义错误的对象感到困惑。

interface Props {
  item?: SomeItem;
}

export const Element = (props: Props) => {
  if (props.item === undefined) {
    return null;
  }

  const offer = offers.find((offer) => offer.id === props.item.offer_id);

  return <div>{props.item.getPayoutPlaceholder()}</div>; 
};

错误是
TS 18048:“ prop .项目”可能是“未定义的”。常量offer = offers.find((offer)=〉offer.id===此.项目.offer_id);
它只在find行显示。最后一行(return)不受此影响。
如果我把props.item赋给一个常量并使用它,它就会停止

const item = props.item;
  if (item === undefined) {
    return null;
  }

  const offer = offers.find((offer) => offer.id === item.offer_id);

我知道在if之后,它可能会被一些异步代码更改。但真正让我困惑的是,它在return语句中没有显示相同的错误。这可能是什么原因呢?

xytpbqjk

xytpbqjk1#

这是因为props.item.offer_id在回调中,所以TS不能确定props.item在你检查它和回调被调用之间没有改变,正如你提到的,你可以通过定义一个常量变量来解决这个问题:

const item = props.item;

还应注意,重构也起作用:

export const Element = ({ item }: Props) => {

但注意,将const更改为let会再次生成原始误差曲面:

let item = props.item;

这是因为现在TS不确定它是否像以前一样没有改变(因为let是可变的并且可以被重新分配)。
props.item.offer_id的用法在return语句中是有效的,因为它不在任何可能延迟执行的上下文中。作为一个例子,在下面的代码中,TS足够聪明地看到这个函数表达式将被立即调用,因此它必须是同步的:

// OK, even though it's in another function
(() => props.item.offer_id)();

无论如何,不管TS为什么会有这样的行为,我建议您使用destructuring directly from the parameter list,它简洁、广泛使用,并且可以直接解决这个问题,而不需要声明额外的常量变量。

相关问题