我正在使用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();
}
此错误与元素类型没有
focus()
方法有关。问题
有没有办法告诉TypeScript
document.activeElement
应该是输入类型?就像是this.focusedElementBeforeDialogOpened = <HTMLInputElement>document.activeElement;
还是有更好的方法解决这个问题,所以声明支持
document.activeElement
和.focus()
的类型? 最佳答案
从document.activeElement的文档中:
也就是说,document.activeElement
不一定是HTMLInputElement
的实例(它也可以是HTMLSelectElement
等)。
如果您确实只在寻找HTMLInputElement
,则可以使用TypeScript可以识别的简单instanceof
类型防护:
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;