Skip to content

Civet

The Modern Way to Write TypeScript

Concise Syntax and Faster Coding with Civet

civet

Civet on the lefttop, compiled TypeScript output on the rightbottom:

Highlights: Beyond TC39

Pipelines

TC39 Proposal: Pipe Operator

data
  |> Object.keys
  |> console.log
console.log(Object.keys(data));

Pipe expression with shorthand functions:

a |> & + 1 |> bar
bar((($) => $ + 1)(a));

Dedented Strings and Templates

TC39 Proposal: String Dedent

text = """
  This text is a string that doesn't include the leading
  whitespace.
"""
text = `This text is a string that doesn't include the leading
whitespace.`;
text = ```
  Also works for
  templates!
```
text = `Also works for
templates!`;

Chained Comparisons

a < b <= c
a is b is not c
a instanceof b not instanceof c
a < b && b <= c;
a === b && b !== c;
a instanceof b && !(b instanceof c);

Default to const for Iteration Items

for (item of [1, 2, 3, 4, 5]) {
  console.log(item * item);
}
for (const item of [1, 2, 3, 4, 5]) {
  console.log(item * item);
}

Modulo Operator

let a = -3
let b = 5
let rem = a % b
let mod = a %% b
console.log rem, mod
const modulo: (a: number, b: number) => number = (
  a,
  b
) => ((a % b) + b) % b;
let a = -3;
let b = 5;
let rem = a % b;
let mod = modulo(a, b);
console.log(rem, mod);

Spread in Any Position

Spreads in first or middle position:

[...head, last] = [1, 2, 3, 4, 5]
const splice: <T>(
  this: T[],
  start: number,
  deleteCount?: number
) => T[] = [].splice as any;
([...head] = [1, 2, 3, 4, 5]),
  ([last] = splice.call(head, -1));
{a, ...rest, b} = {a: 7, b: 8, x: 0, y: 1}
({ a, b, ...rest } = { a: 7, b: 8, x: 0, y: 1 });
function justDoIt(a, ...args, cb) {
  cb.apply(a, args)
}
const splice: <T>(
  this: T[],
  start: number,
  deleteCount?: number
) => T[] = [].splice as any;
function justDoIt(a, ...args) {
  let [cb] = splice.call(args, -1);
  return cb.apply(a, args);
}

Import Syntax Matches Destructuring

import {X: LocalX, Y: LocalY} from "./util"
import { X as LocalX, Y as LocalY } from "./util";

Export Convenience

export a, b, c from "./cool.js"
export x = 3
export { a, b, c } from "./cool.js";
export var x = 3;

Single-Argument Function Shorthand

x.map &.name
x.map &.profile?.name[0...3]
x.map &.callback a, b
x.map +&
x.map(($) => $.name);
x.map(($1) => $1.profile?.name.slice(0, 3));
x.map(($2) => $2.callback(a, b));
x.map(($3) => +$3);

INFO

Short function block syntax like Ruby symbol to proc, Crystal, or Elm record access

Custom Infix Operators

operator {min, max} := Math
value min ceiling max floor
const { min, max } = Math;
max(min(value, ceiling), floor);

Everything is an Expression

items = for item of items
  if item.length
    item.toUpperCase()
  else
    "<empty>"
x == null ? throw "x is null" : x.fn()
items = (() => {
  const results = [];
  for (const item of items) {
    if (item.length) {
      results.push(item.toUpperCase());
    } else {
      results.push("<empty>");
    }
  }
  return results;
})();
x == null
  ? (() => {
      throw "x is null";
    })()
  : x.fn();

JSX

function Listing(props)
  <h1 #heading>Hello Civet!
  <ul .items>
    <For each=props.items>
      (item) =>
        <li .item {props.style}><Item {item}>
function Listing(props) {
  return (
    <>
      <h1 id="heading">Hello Civet!</h1>
      <ul class="items">
        <For each={props.items}>
          {(item) => {
            return (
              <li
                class="item"
                style={props.style}
              >
                <Item item={item} />
              </li>
            );
          }}
        </For>
      </ul>
    </>
  );
}

Sponsors

Thank you to all of our sponsors for your invaluable support and contribution to the Civet language!

Support the future development of Civet!

Contributors

Thank you for your work and dedication to the Civet project!

Civet v0.5.59