在类型为“EventTarget”的对象上,不存在属性“selectionStart”。

7

我正在使用selectionStartselectionEnd来获取文本选择的起始点和结束点。

代码: https://codesandbox.io/s/busy-gareth-mr04o

然而,我无法确定它们可以在哪种类型的事件上调用。 如果我使用any,代码可以正常工作,但我更想知道正确的事件类型。

我已经尝试了以下这些类型: Element React.SyntheticEvent<HTMLDivElement> <HTMLDivElement> 但都没有成功。

export default function App() {
  const [startText, setStartText] = useState<number | undefined>();
  const [endText, setEndText] = useState<number | undefined>();

  const handleOnSelect = (event: any) => { <--- I CANNOT FIND THE RIGHT EVENT TYPE
    setStartText(event.target.selectionStart);
    setEndText(event.target.selectionEnd);
  };

  return (
    <Grid container direction="column" className="App">
      You can type here below:
      <TextField
        value={"This is a example, select a word from this string"}
        onSelect={(event) => handleOnSelect(event)}
      />
      <br />
      <Grid item>The selected word starts at character: {startText}</Grid>
      <Grid item>The selected word ends at character: {endText}</Grid>
    </Grid>
  );
}
1个回答

10

这是一个棘手的问题,因为material-ui的TextField组件涉及多个嵌套节点。传递给onSelect函数的参数是一个div。然而事件本身发生在div内部的一个input上。

const handleOnSelect = (event: React.SyntheticEvent<HTMLDivElement, Event>) => {
    console.log(event.target, event.currentTarget);
};

这将记录输入,然后记录div

使用event.currentTarget获取非常具体的TypeScript信息。我们知道它是一个HTMLDivElement。但是div没有我们想要访问的selectionStartselectionEnd属性。这些属性存在于input中。

event.target为我们提供了一个非常模糊的类型EventTarget。我们不知道目标是一个input

一种选择是在运行时验证元素。

const handleOnSelect = (event: React.SyntheticEvent<HTMLDivElement, Event>) => {
    if ( event.target instanceof HTMLInputElement ) {
        setStartText(event.target.selectionStart);
        setEndText(event.target.selectionEnd);
    }
};

由于您知道事件始终会发生在HTMLInputElement上,我认为可以放心地做出断言。

const handleOnSelect = (event: React.SyntheticEvent<HTMLDivElement, Event>) => {
    const target = event.target as HTMLInputElement;
    setStartText(target.selectionStart);
    setEndText(target.selectionEnd);
};

请注意,selectionStartselectionEnd属性使用null而不是undefined。因此,您需要将状态类型更改为<number | null>,或者通过使用null合并运算符event.target.selectionStart ?? undefinednull替换为undefined

1
非常感谢!我选择了 const target = event.target as HTMLInputElement,因为 if 语句总是被跳过 (event.target instanceof HTMLInputElement)。 - Magofoco

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