What & Why
Type Annotations
Type AnnotationsPrimitive TypesNull and UndefinedBooleanNumberBigIntStringSymbolUnknown TypeOptional TypesUnion TypesFunction TypesObject TypesClass TypesArray TypesTuple TypesType AliasesGeneric TypesMagic TypesModules
Type System
For Potential Contributors

Primitive Types


Imagine type as a Set of different values. Some of them are finite and some are not. In nowadays JavaScript has 7 primitive types:

  • Null
  • Undefined
  • Boolean
  • Number
  • BigInt
  • String
  • Symbol

Hegel has not only the same types, but also adds several new types. Let's discover each of them:

Null and Undefined

The most primitive types in JavaScript are null and undefined, because each of them contains only one value. You can define variable with this datatype in Hegel:

let emptyValue: null = null;
let undefinedValue: undefined = undefined;

As you can see null and undefined types have the same name as their literals, but some datatypes do not. In Hegel you can annotate your variables/object properties with both literal value and datatype name.


The second primitive type is boolean, because it contains only two values: true and false.

// Using literal as a datatype
let canIContain4Values: false = false;
let canIUseLiteralAsTypeAnnotation: true = true;
// Using expressions
let canIUseWithExpressions: boolean = !canIContain4Values;


JavaScript Number datatype presents any signed 64-bit number. JavaScript has not different datatypes for floating or unsigned numbers. -1, 2.7182 and 0xff will have the same datatype - number. Also, JavaScript has "special" identifiers: Infinity and NaN which also included in number datatype (And in JavaScript is existed -0, but this is a long story). In Hegel you can annotate your variable/object property with number datatype name or with literal in different format (hexademical, binary, exponential and etc.)

let decimal: 6 = 6;
let hex: 0xf00d = 0xf00d;
let binary: 0b1010 = 0b1010;
let octal: 0o744 = 0o744;
let anyNumber: number = decimal + hex + binary + octal;


BigInt was added in ES2019 and presents any integer number without bits limitations.

let reallyBigNumber: bigint = 2n ** 255n;

Warning: BigInt is not subtype or super type for Number data type. Hegel will show you an error if you try to use bigint as number or number as bigint. Also, in JavaScript you can't mix number and bigint in math operators, so, Hegel will show you an error too.

// Error: Type "bigint" is incompatible with type "number"
const usageBigIntAsNumber: number = 4n + 2n;
// Error: Type "number" is incompatible with type "bigint"
const usageNumberAsBigInt: bigint = 4 + 2;
// Error: Type "4n" is incompatible with type "number"
4 * 4n;
// Error: Type "255" is incompatible with type "bigint"
2n ** 255;


Unlike String in other programming languages, JavaScript's String has a value (not reference) behavior. So, any characters set wrapped in single quote ('), double quote (") or backtick/backquote (`) will be a valid JavaScript string literal. In Hegel you can annotate variable/object property with both literal or string datatype name, the same as with other datatypes.

const firstName: "Robert" = "Robert";
const lastName: "Paulson" = "Paulson";
const fullName: string = firstName + " " + lastName;
const sentence: string = `His name is ${fullName}.`;

JavaScript implicitly converts other types of values into strings by concatenating them.

44 + "6"; // 446

Hegel implements a strong type system, so it will accept only strings when concatenating them or when template literal is used.

const world = {
toString() {
return "World";
"Hello " + "World"; // 👌!
// Error: Type "42" is incompatible with type "string"
"Hello " + 42;
// Error: Type "{ toString: () => string }" is incompatible with type "string"
"Hello " + world;
// Error: Type "{ toString: () => string }" is incompatible with type "string"
`Hello, ${world}`;

To prevent error you need explicity convert value to string:

const world = {
toString() {
return "World";
"Hello " + "World"; // 👌!
"Hello " + String(42); // 👌!
"Hello " + String(world); // 👌!
`Hello, ${String(world)}`; // 👌!


Symbol is another "new" datatype which was included in language starting from ECMAScript 2015. Symbols are created by Symbol function invocation in JavaScript. Hegel provides symbol datatype that can be used as type annotation.

const unique: symbol = Symbol("unique");

Warning: Symbol datatype has not any literal, so you can not use symbol values as datatype.

// Error: Unexpected token
const unique: Symbol("unique") = Symbol("unique");