Skip to content

Removed TypeScript constructs

What Hem does not accept from JavaScript and TypeScript, and the typed replacement for each.

Updated View as Markdown

The removed constructs below are unwritable in Hem source. Removed words stay reserved as ordinary identifiers. null and undefined are admitted inside type expressions to preserve exact TypeScript contracts; their value literals remain removed.

Removed, with replacements

Construct Status Replacement
const Removed Write let: Hem’s let is TypeScript’s const
var, function, switch, loose == Removed let, arrows, match, strict ==
Truthiness, null and undefined literals Removed Boolean conditions, ??, None, ?T
any Demoted on contact unknown plus narrowing, cast inserted automatically
enum, interface, namespace, declaration merging Removed Variants, type, modules
this outside classes, arguments Removed Closures, rest parameters
Key-iterating for..in, C-style for, do..while, labels Removed Value for..in, ranges, while
++, --, the comma operator Removed +=, statements
Unchecked indexing Removed xs[i] is ?T
Statement-only exception handling Demoted Postfix catch everywhere; try remains as a residual form

T | null and T | undefined are exact type contracts; ?T admits both sentinels. Use contextual None in value position. This type syntax does not enable unchecked assertions or authored predicate promises.

Operator restrictions

== compiles to ===. Coercing equality is not expressible. The single exception is == and != against None, which emit == null and != null so that one evaluation eliminates both nullish members.

Conditions, !, &&, and || accept boolean operands only. A non-boolean condition reports HEM2002.

Binary + and += are arithmetic only: both operands number, or both bigint. Operands cannot be strings or mixed numeric types. Unary + requires an operand that is already number, rather than performing runtime conversion like Number(x). All three cases report HEM2021. String concatenation has one spelling, a template literal.

Words that are not removed

type and error are contextual keywords. They open a declaration only at the start of a statement with an identifier following, as in type Id = string or error NotFound({ id: string }).

Everywhere else they are ordinary identifiers. All of the following are plain code:

let error = validate(input)
let handler = (type: string) => type
let { type } = event
let tag = event.type

brand is contextual in one position, immediately after a type declaration’s =. deriving is active only in a deriving Eq clause on a variant or error declaration.

Statement results must be used

A statement whose only outcome is to compute and discard a value reports HEM2018. Two shapes are refused.

The syntactic tier covers statements that cannot have any effect: a bare name, a field or index access, a literal, or a comparison.

The type-directed tier covers a call or await whose checked result is a carrier by declaration origin: canonical standard Option or Result, an Effect, a Promise or PromiseLike, or a boxed Option or Result from the Effect transport. Canonical carriers remain must-use when Effect is disabled.

Ordinary side-effecting calls stay legal because their results are not carriers, including array.push, map.set, and console.log. A ?T is not a carrier.

The deliberate discard is let _ = expression, which emits void (expression); and leaves no unused TypeScript binding.

Emit guarantees

Emitted TypeScript contains no enums, namespaces, or parameter properties. Output runs unmodified under Node type stripping and TypeScript’s erasableSyntaxOnly.

Normative source

Specification 0.2, §15 (removed constructs), §6 (operators and must-use), §2 (lexical structure).

Navigation

Type to search…

↑↓ navigate↵ selectEsc close