代码之家  ›  专栏  ›  技术社区  ›  Trade-Ideas Philip

确保TypeScript中的对象类型

  •  0
  • Trade-Ideas Philip  · 技术社区  · 4 年前

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

    这个 throw 是必需的。getElementById()返回类型 HTMLElement | null ,它不支持disabled属性。之后 类型正确地更改为 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)) . 同样,我正在尝试执行运行时检查并满足编译器的要求。我想尽量避免打字。

    1 回复  |  直到 4 年前
        1
  •  2
  •   Cerberus    4 年前

    这比我预期的要难一点,但它起作用了:

    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");
        }
    }
    

    Playground

    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>
        2
  •  1
  •   Trade-Ideas Philip    4 年前

    这是基于公认的答案。

    /**
     * This is a wrapper around document.getElementById().
     * This ensures that we find the element and that it has the right type or it throws an exception.
     * Note that the return type of the function matches the requested type.
     * @param id Look for an element with this id.
     * @param ty This is the type we are expecting.  E.g. HtmlButtonElement
     */
    function getById<T extends Element>(id : string, ty: {new(): T}): T {
      const found = document.getElementById(id);
      if (!found) {
        throw new Error("Could not find element with id " + id + ".  Expected type:  " + ty.name);
      }
      if (found instanceof ty) {
        return found;
      } else {
          throw new Error("Element with id " + id + " has type " + found.constructor.name + ".  Expected type:  " + ty.name);
      }
    }
    
        3
  •  0
  •   Declan Fitzpatrick    4 年前
    export function isHTMLButtonElement(value: any): value is HTMLButtonElement
        {
            return value instanceof HTMLButtonElement;
        }
    

    类似于此,返回类型指定它是一个HtmlButtoneElement。代码可能会更好,但您得到了jist:)

    const button = document.getElementById(id) as HTMLButtonElement;