TypeScript/JSX类型断言仅在JSX之外有效

7

我有一个React组件,可以通过一个数组进行映射。

每个数组项都有一个可选的ID类型。

如果我有这个ID,我将渲染一个元素,否则什么也不做。

该元素具有一个onClick事件,它调用一个函数并接受ID作为参数。

即使我检查过是否有ID,TypeScript仍然会抱怨ID可能是未定义的,但只会在onClick方法内部才会出现此问题(请参阅代码示例)。

为什么会这样?如何消除这个错误?

请查看TypeScript PlayGround中的错误

在这里输入图片描述

// fake bindings
declare namespace React {
  function createElement(): any;
}

// This type has an optional prop
type SampleType = {
  id?: string;
  name: string;
}

const sampleArray: SampleType[] = [{id: 'test', name: 'Adrian'}, {name: 'Florescu'}]

function sampleFunction(id: string){
  console.log('ID', id);
}

function SampleComponent() {
  return (
    <div>
      {sampleArray.map((item: SampleType) => {
        if(item.id) {
          sampleFunction(item.id); // This works
          return <p onClick={() => { sampleFunction(item.id); }}>{item.name}</p>; //// This does not work
        }
      })}
    </div>
  )
};

const dom = <SampleComponent />;

2
当您发布问题时,我注意到您发布了TypeScript playground链接“原始”(因此它既是链接又是文本)。我进行了编辑,使其成为带有文本标签的链接,但它却出现了问题。我设法修复了它,但无法理解为什么会出现问题。我已经找到了答案。只是提一下,因为现在,如果您想要链接到TypeScript的新playground,您需要使用这个解决方法。 - T.J. Crowder
1个回答

7

这不是JSX的问题,而是时序问题。 :-) 由于点击事件发生得比较晚,因此从TypeScript的角度来看,在你检查它和在需要使用字符串的地方使用它之间,id可能已经变成了undefined。这里也会发生同样的事情:

setTimeout(() => {
  sampleFunction(item.id); // Same error occurs
}, 1000);

解决方法是使这不可能发生。其中一种选项是捕获id(同时我们也可以捕获name):
if(item.id) {
  const {id, name} = item;
  return <p onClick={() => { sampleFunction(id); }}>{name}</p>; // This works now
}

更新的实验室


3
明白的,谢谢你 T.J. Crowder! - Adrian Florescu
1
@AdrianFlorescu - 这是一个有趣的经历。 :-) - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接