All Projects → keyboardDrummer → typeless

keyboardDrummer / typeless

Licence: MIT license
Typeless: the benefits of TypeScript, without the types

Programming Languages

scala
5932 projects
typescript
32286 projects

Projects that are alternatives of or similar to typeless

birthtalk
Meet who have birth common with you
Stars: ✭ 36 (+111.76%)
Mutual labels:  tdd
my-react-todolist
A guide to TDD a React/Redux TodoList App
Stars: ✭ 22 (+29.41%)
Mutual labels:  tdd
tensorflowjs-remove-background
Remove Background from the picture using WebAssembly & TensorFlow.js
Stars: ✭ 79 (+364.71%)
Mutual labels:  tdd-javascript
chai
BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
Stars: ✭ 7,842 (+46029.41%)
Mutual labels:  tdd
Aec-Library-Website
This is an Open-Source Library Website in which you get Resources to learn different topics, Donate book section to donate your old books, and a Book issue section to keep a record of all the books issued. -HacktoberFest Accepted
Stars: ✭ 52 (+205.88%)
Mutual labels:  javascript-tools
goss
Quick and Easy server testing/validation
Stars: ✭ 26 (+52.94%)
Mutual labels:  tdd
slick
Vim/Neovim Colortheme–Truecolor, Stunning, Complete
Stars: ✭ 15 (-11.76%)
Mutual labels:  javascript-tools
ko-component-tester
🚦 TDD Helpers for Knockout JS
Stars: ✭ 15 (-11.76%)
Mutual labels:  tdd
memo
다양한 MD 메모
Stars: ✭ 87 (+411.76%)
Mutual labels:  tdd
learn-ramda
🐏 Learn ramda, the interactive way
Stars: ✭ 84 (+394.12%)
Mutual labels:  javascript-tools
chai-exclude
Exclude keys to compare from a deep equal operation with chai expect or assert.
Stars: ✭ 33 (+94.12%)
Mutual labels:  tdd
finance-project-ddd
Projeto financeiro usando domain driven design, tdd, arquitetura hexagonal e solid
Stars: ✭ 67 (+294.12%)
Mutual labels:  tdd
mugshot
Framework independent visual testing library
Stars: ✭ 126 (+641.18%)
Mutual labels:  tdd
Unmockable
💉 ↪️ 🎁 Unmockable objects wrapping in .NET
Stars: ✭ 35 (+105.88%)
Mutual labels:  tdd
eye drops
Configurable Elixir mix task to watch file changes and run the corresponding command.
Stars: ✭ 51 (+200%)
Mutual labels:  tdd
TDD
Everything about testing, especially TDD, Test-Driven Development: Really, It’s a Design Technique
Stars: ✭ 28 (+64.71%)
Mutual labels:  tdd
Examin
Examin is a developer tool that generates React unit tests for your application. Ensure your application renders as expected before adding new features. Examin writes the baseline unit tests and allows developers to customize their tests for their application.
Stars: ✭ 75 (+341.18%)
Mutual labels:  tdd
colorizzar
📗 -> 📘 Change color of png keep alpha channel in php!
Stars: ✭ 27 (+58.82%)
Mutual labels:  tdd
doctest
The fastest feature-rich C++11/14/17/20 single-header testing framework
Stars: ✭ 4,434 (+25982.35%)
Mutual labels:  tdd
TheVimIDE
Modern Vim IDE with support for C/C++, Java, Python, Lua, PHP, JavaScript, Ruby and much more ...
Stars: ✭ 33 (+94.12%)
Mutual labels:  javascript-tools

Typeless: the benefits of TypeScript, without the types

Typeless provides great editor tooling for plain JavaScript. Typeless uses unit tests instead of type annotations to understand source code. Here's a demo of some Typeless features:

Features demo

You can see features you're used to from languages such as TypeScript:

  • Inline syntax and semantic errors
  • Code completion
  • Hover tooltips over variables
  • User written documentation is shown in the tooling
  • Code navigation such as go to definition and find references
  • Assisted rename refactoring

There are also features that you don't normally see:

  • Inline errors for failed tests are shown not where the exception occurred, but where the bug likely is.
  • There are no references to types anywhere, everything is shown using values.

For a comparison between TypeScript and Typeless, go here. For a comparison between JavaScript and Typeless, go here.

How do I get it?

Typeless is currently in the prototype phase. You can only use it by building it from source.

Steps to try Typeless:

  • Make sure VSCode can be run from your path using code. More information is here.
  • Install the Mill build tool by following these instructions.
  • Run mill server.vscode to start VSCode with the Typeless extension.
  • Create a .tl, write some JavaScript and a function ending in Test.

Because Typeless depends on running tests, it's important to always write tests before writing the implementation, also called test-driven development, when using Typeless.

If you're interested in Typeless, please star the GitHub page or upvote the post that brought you here. Contributions are much appreciated.

FAQ

Why use JavaScript and Typeless when I can use TypeScript?

Languages with type systems often provide some level of safety without asking the programmer to provide any type annotations. One scenario is when the programmer uses code from a library that already has type annotations, for example when using the + operator that's part of the JavaScript specification:

function doesNotCompile() {
  return true + 3;
         ^^^^^^^^
  // Operator '+' cannot be applied to types 'boolean' and 'number'.
} 

Another situation in which programmers get safety for free is when type inference is performed, for example:

function doesNotCompile() {
  var person = { name: 'Remy' }
  person.age
         ^^^
  // Property 'age' does not exist on type '{ name: string; }'
}

However, type inference only works for part of the code, and the programmer has to write type annotations where it doesn't or otherwise risk losing the safety provided by types. For TypeScript, type annotations should be provided on all function signatures since there is no type inference on them.

As TypeScript applications get more complex, so do the types required to describe them. The TypeScript handbook features a section called Advanced types. Here's an example of a program that uses advanced types to implement the pipe function, which takes multiple functions as an argument and pipes them all together, like UNIX pipes.

type Person = { name: string }
function pipeTest() {
  const isNameOfEvenLength = pipe((person: Person) => 
    person.name, (str: string) => str.length, (x: number) => x % 2 == 0);
  assert(isNameOfEvenLength({ name: "Remy" }))
  assert(!isNameOfEvenLength({ name: "Elise" }))
}

type ArityOneFn = (arg: any) => any;
type PickLastInTuple<T extends any[]> = 
  T extends [...rest: infer U, argn: infer L ] ? L : never;

const pipe = <T extends ArityOneFn[]>(...fns: T) => 
  (p: Parameters<T[0]>[0]): ReturnType<PickLastInTuple<T>> => 
  fns.reduce((acc: any, cur: ArityOneFn) => cur(acc), p);

Note how the function pipe in the above program has only one line of implementation, but five lines to describe its type. Worse, even with all these types, the type checker will not guarantee that the functions passed to pipe all fit together.

In case you had trouble reading the above, these articles explain most of the type-level features used:

The types in the above program have become a little program of their own, and understanding which values are part of this type requires mentally executing this type-level program. We want to offer programmers the opportunity to avoid doing such mental gymnastics and work with a type-free language.

Conceptually, we view type-checking as a way of formally proving that a particular class of errors does not occur in a program. Because compilers are limited in the extend to which they can provide these proofs automatically, the programmer is often required to provide type annotations to help the compiler. For programmers who are not interested in providing formal correctness proofs of their program, we want to offer a typeless programming experience.

I write types to design my program. Does that mean Typeless is not for me?

Defining what data structures your program will work with is an important step in the development process. In Typeless, you can define your data structures by writing their constructors.

Consider the following TypeScript program:

interface List<T> { }
class Node<T> extends List<T> {
  head: T;
  tail: List<T>;

  constructor(head: T, tail: List<T>) {
    this.head = head;
    this.tail = tail;
  }
}
class Nil extends List<never> {
}
const nil = new Nil();

The Typeless equivalent:

function NodeConstructorTest() {
  new Node(3, new Node("hello", nil));
}

class Node {
  constructor(head, tail) {
    this.head = head;
    this.tail = tail;
  }
}

const nil = {};

Note the Typeless program uses fewer concepts: there are no generics, no interfaces, no class inheritance and no never type. However, the Typeless program is more ambiguous about what values may be passed to the Node constructor. A seasoned Typeless programmer may opt to use generators to remove that ambiguity by writing the following test:

function NodeConstructorTest() {
  let listGenerator;
  const nodeGenerator = generators.new(() => new Node(generators.value.pop(), listGenerator.pop()));
  listGenerator = generators.any(nil, nodeGenerator)
  nodeGenerator.pop();
}

The above test requires knowledge of generators. We believe using generators to define data structures has two advantages over using types:

  • It requires fewer concepts.
  • Generators can also be used to write powerful tests.

We can showcase the last argument by adding a length method to the Node class and writing a test for it:

function NodeLengthTest() {
  const tail = listGenerator.pop();
  const node = new Node(undefined, tail);
  assert(node.length, tail.length + 1)
}

class Node {
  constructor(head, tail) { .. }

  length() { return 1 + tail.length }
}

const nil = { 
  length: () => 0;
};

Why not use the JavaScript support in TypeScript's LSP server instead of Typeless?

The existing TypeScript language server that's included in the TypeScript repository can also be used to provide editor support for JavaScript programs. Here's an example:

function foo() {
  var person = { name: Remy, age: 31 };
  person.
  // We get autocompletion for name and age after typing the dot

  person.name
  // Executing go to definition on "name" jumps to "name" in "{ name: Remy, age: 31 }";
}

However, the JavaScript language tooling provided by the TypeScript language server depends on type inference. It performs type inference within the body of a function, but not on the signatures of functions themselves, causing editor tooling to break down when doing function calls. Here's an example:

function foo() {
  var person = { name: Remy, age: 31 };
  usePerson(person)
}

function usePerson(person) {
  person.
  // After typing the dot, no semantic code completion is provided. 
  // There is only textual code completion based on what other identifiers occur in this file, 
  // for example 'person' is in the list.
}

Since type inference only works in parts of the program, type-based JavaScript editor tooling is not able to match TypeScript editor tooling.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].