我正在使用TypeScript和React.在我的组件(对话框窗口)中,我想存储触发器元素,例如按钮作为属性.当组件卸载时,我想将焦点返回到该元素.但是,我收到TSLint的错误,我不知道如何解决.
class Dialog extends React.Component<Props, {}> {
...
focusedElementBeforeDialogOpened: HTMLInputElement;
componentDidMount() {
this.focusedElementBeforeDialogOpened = document.activeElement;
...
}
...
}
我在分配属性值的行上收到错误:
[ts] Type 'Element' is not assignable to type 'HTMLInputElement'.
Property 'accept' is missing in type 'Element'.
但是,如果我将属性的类型更改为Element甚至HTMLInputElement,我会在componentWillUnmount()中收到错误
componentWillUnmount() {
...
this.focusedElementBeforeDialogOpened.focus();
}
此错误与Element类型没有focus()方法有关.
题
有没有办法告诉TypeScript document.activeElement应该是一个输入类型?就像是
this.focusedElementBeforeDialogOpened =< HTMLInputElement> document.activeElement;
或者是否有更好的方法来声明支持document.activeElement和.focus()的类型?
最佳答案 来自
document.activeElement的文档:
Often this will return an
<input>
or<textarea>
object, if it has the text selection at the time. If so, you can get more detail by using the element’s selectionStart and selectionEnd properties. Other times the focused element might be a<select>
element (menu) or an<input>
element, of type button, checkbox or radio.
也就是说,document.activeElement不一定是HTMLInputElement的实例(它也可以是HTMLSelectElement等).
如果您确实只是在寻找HTMLInputElement,则可以使用TypeScript识别的简单实例type-guard:
componentDidMount() {
if (document.activeElement instanceof HTMLInputElement) {
this.focusedElementBeforeDialogOpened = document.activeElement;
}
...
}
此外,您可以检测元素是否可聚焦,例如通过定义自己的类型保护:
interface IFocusableElement {
focus(): void;
}
function isFocusable(element: any): element is IFocusableElement {
return (typeof element.focus === "function");
}
然后使用IFocusableElement作为this.focusedElementBeforeDialogOpened的类型和您自己的类型保护:
focusedElementBeforeDialogOpened: IFocusableElement;
componentDidMount() {
if (document.activeElement && isFocusable(document.activeElement)) {
this.focusedElementBeforeDialogOpened = document.activeElement;
}
...
}
如果您还需要Element提供的原始API,您可以使用交集类型:
focusedElementBeforeDialogOpened: IFocusableElement & Element;