Using TypeScript in the Browser Without a Framework

Based on this commit and [Minimalist TypeScript Bundling for Modern Browsers].

You can't reference function names directly from HTML because the build step puts them inside a scope rather than keeping them globally available. So instead of this.

<button onclick="fetchData()">Fetch Data</button>

You can instead give the element an id, access it via query selector, and attach the handler directly.

<button id="fetchBtn">Fetch Data</button>

When you're not using a framework, you end up doing enough DOM manipulation that some convenience functions can be very helpful. A couple of basic ones are below, which accept a normal CSS query string.

export const $ = <T extends HTMLElement = HTMLElement>(query: string) => {
  if (query.startsWith('#')) {
    return document.getElementById(query.substr(1)) as T
  }
  if (query.startsWith('.')) {
    return document.getElementsByClassName(query.substr(1))[0] as T
  }
  return document.getElementsByTagName(query.substr(1))[0] as T
}

export const $$ = <T extends HTMLElement = HTMLElement>(query: string) => {
  return document.querySelectorAll(query) as NodeListOf<T>
}

These functions allow the specification of an element type so the returned items have the correct properties.

$<HTMLButtonElement>('#fetchBtn').onclick = fetchData
$<HTMLSelectElement>('#animal').value
$<HTMLInputElement>('#useArrow').checked