首页 > 解决方案 > 确保 TypeScript 中的对象类型

问题描述

我正在为浏览器使用 TypeScript。我发现自己写了很多这样的代码:

const button = document.getElementById(id);
if (!(button instanceof HTMLButtonElement)) {
  throw new Error("TODO -- insert better error message here");
}
button.disabled = false;

throw是必需的。getElementById() 返回 type HTMLElement | null,它不支持 disabled 属性。throw类型正确更改为后HTMLButtonElement。我可以使用类型断言来完成此操作,但此代码还包括运行时检查。

有什么办法可以把它变成一个函数吗?就像是:

const button = verify(document.getElementById(id), HTMLButtonElement);
button.disabled = false;

或者

const button = verify<HTMLButtonElement>(document.getElementById(id));
button.disabled = false;

但不是

const button = verify<HTMLButtonElement>(document.getElementById(id), HTMLButtonElement);
button.disabled = false;

因为那时我输入了两次相同的单词,我很容易出错。

在 Java 或 C# 中,我会说(HTMLButtonElement)document.getElementById(id)而不是verify(). 在 C++ 中,我会说dynamic_cast< HTMLButtonElement & >(document.getElementById(id)). 同样,我正在尝试进行运行时检查并满足编译器的要求。我想尽可能避免打字。

标签: typescript

解决方案


这比我预期的要难一些,但它有效:

function verify<T extends Element>(element: Element | null, ty: {new(): T}): T {
    if (element === null) {
        throw new Error("TODO: element is null");
    }
    if (element instanceof ty) {
        return element;
    } else {
        throw new Error("TODO: wrong type");
    }
}

操场

这是一个检查正确性的片段:

function verify(element, ty) {
  if (element === null) {
    throw new Error("TODO: element is null");
  }
  if (element instanceof ty) {
    return element;
  } else {
    throw new Error("TODO: wrong type");
  }
}

function enableButton(id) {
  const button = verify(document.getElementById(id), HTMLButtonElement);
  button.disabled = false;
}

enableButton("button");
try {
  enableButton("not_exist");
} catch (e) {
  console.error(e);
}
try {
  enableButton("not_a_button");
} catch (e) {
  console.error(e);
}
button:disabled {
  color: grey;
}
<div id="not_a_button"></div>
<button id="button" disabled>Enabled</button>
<button id="disabled_button" disabled>Disabled</button>


推荐阅读