Unfortunately, the project is closed and will not be developed anymore. The reasons are described here.
Getting Started | Documentation | Gitter Chat
Hegel is a type checker for JavaScript with optional type annotations and preventing runtime type errors.
TypeError
that may be thrown in runtime..d.ts
files as the source of typings for any libraries.To read more about Hegel, check out Docs.
TypeScript never will guarantee that you will not have a Type Error at Runtime. Check TypeScript non-goals point 3. Hegel is on the opposite side. We try to implement a strong and sound type system that will guarantee that your program is valid.
As example (You can try it in our playground):
const numbers: Array<number> = [];
// HegelError: Type "Array<number>" is incompatible with type "Array<number | string>"
const numbersOrStrings: Array<string | number> = numbers;
numbersOrStrings[1] = "Hello, TypeError!";
// HegelError: Property "toFixed" does not exist in "Number | undefined"
numbers[1].toFixed(1);
The same example with TypeScript (v3.8.3)
compiles without any error, but you will have 2 TypeError
in runtime.
Hegel is targeting at really powerful type inference which gives an ability to write fewer type annotations.
As example (You can try it in our playground):
const promisify = (fn) => (arg) => Promise.resolve(fn(arg));
const id = promisify((x) => x);
// And "upperStr" will be inferred as "Promise<string>"
const upperStr = id("It will be inferred").then((str) => str.toUpperCase());
The same example with TypeScript (v3.8.3)
will throw 2 errors and inference upperStr
as Promise<any>
.
Hegel gives you information about errors that may be thrown by functions/methods.
Example of error type inference
// If you hover at function name you will see it type as "(unknown) => undefined throws RangeError | TypeError"
function assertPositiveNumber(value) {
if (typeof value !== "number") {
throw new TypeError("Given argument is not a number!");
}
if (value < 0) {
throw new RangeError("Given number is not a positive number!");
}
}
As you understand, you will have the same error type in try-catch
block.
Example:
try {
assertPositiveNumber(4);
} catch (e) {
// Hegel inference `e` type as "RangeError | TypeError | unknown"
}
The same example with TypeScript (v3.8.3)
will throw one error and e
type will be any
.
Flow.js has custom library definition languages and doesn't support the most popular TypeScript "d.ts" format. But for Hegel TypeScript "d.ts" it the only way to create type definition for library. So, every library which has TypeScript definitions should work with Hegel.
Hegel inferences function type by function declaration when Flow inferences function type by usage. As example (You can try it in our playground):
const id = (x) => x;
// Hegel inference type of "num" variable is "number"
let num = id(4);
// And type of "str" as "string"
let str = id("4");
The same example with Flow (v0.123.0)
will inference both num
and str
as number | string
.
Hegel gives you information about errors that may be thrown by functions/methods.
Example of error type inference
// If you hover at function name you will see it type as "(unknown) => undefined throws RangeError | TypeError"
function assertPositiveNumber(value) {
if (typeof value !== "number") {
throw new TypeError("Given argument is not a number!");
}
if (value < 0) {
throw new RangeError("Given number is not a positive number!");
}
}
As you understand, you will have the same error type in try-catch
block.
Example:
try {
assertPositiveNumber(4);
} catch (e) {
// Hegel inference `e` type as "RangeError | TypeError | unknown"
}
The same example with Flow (v0.123.0)
will inference e
type as empty
.
Step 1: check your Node.js version:
$ node -v
v12.0.0
Hegel was developed for current LTS version of Node.js (12.16.1). So, you need to have at least 12 version.
If you have less than 12 version of Node.js you may change it to 12 or latest by nvm
.
Step 2: install @hegel/cli
with npm globally or locally:
# globally
$ npm install -g @hegel/cli
# locally
$ npm install -D @hegel/cli
Step 3. You already can use it into your JavaScript project:
# globally
$ hegel
No errors!
# locally
$ npx hegel
No errors!
Hegel has a zero-configuration, but if you want to change settings see Configuration Section.
Step 4. Hegel is already configured, but, you need to compile your project to plain JavaScript.
If you use Babel:
Add into .babelrc
file (or create .babelrc
file at the root of your project with) next content:
{
"presets": [["@babel/preset-flow", { "all": true }]]
}
And install @babel/preset-flow
$ npm i -D @babel/core @babel/cli @babel/preset-flow
Add script inside your package.json:
{
"name": "your-project",
"scripts": {
"build": "babel directory_with_your_project_files/ -d compilation_destination_directory/"
}
}
If you don't use Babel: The same as Flow, you can use flow-remove-types.
Install flow-remove-types
:
$ npm i -D flow-remove-types
And add next script inside your package.json
scripts
section:
{
"scripts": {
"build": "flow-remove-types directory_with_your_project_files/ --out-dir compilation_destination_directory/ --all"
}
}
Finally. You can compile your project by:
$ npm run build
There are few separated packages in Hegel project:
You will need to install Git, nodejs, npm and yarn
it is HIGHLY RECOMMENDED to install nodejs (and npm) with nvm and then yarn with npm like so npm -g i yarn
required versions of sayed software are listed below
node: ^12.16.3
npm: ^6.14.4
yarn: ^1.22.4
Open Terminal and copy paste following commands
# clone the repo
git clone git@github.com:JSMonk/hegel.git
# cd into the repo
cd hegel
# install all dependencies
yarn
# build core and cli
yarn build
Currently, all tests are written for @hegel/core, so, if you will change code inside @hegel/core package, you can run tests by:
yarn test
Hegel is MIT-licensed (LICENSE).