Civet Language

Das bessere TypeScript?

21.03.2023
Von 
Matthew Tyson ist Java-Entwickler und schreibt unter anderem für unsere US-Schwesterpublikation Infoworld.com.
Civet ist ein modernes Superset von TypeScript und kann Ihnen raffinierte, zusätzliche Funktionen erschließen.
Civet hat seinen Namen von der Zibetkatze und ist laut seinen Machern "der moderne Weg, TypeScript zu schreiben".
Civet hat seinen Namen von der Zibetkatze und ist laut seinen Machern "der moderne Weg, TypeScript zu schreiben".
Foto: airdone - shutterstock.com

Civet wird als eine Art modernes CoffeeScript für TypeScript beschrieben - was nicht gerade schmeichelhaft ist, wenn man sich an CoffeeScript erinnert. Allerdings sollten Sie Civet dennoch nicht vorschnell abschreiben: Es handelt sich um eine kompakte, moderne Programmiersprache, die verspricht, alle geschätzten TypeScript-Features einfacher und performanter zur Verfügung zu stellen - inklusive Zugriff auf ECMAScript-Sprachfunktionen. Angesichts der Möglichkeiten, die Civet - mit sehr wenig Aufwand - bietet, könnten Sie überrascht sein.

Was ist Civet?

Da Civet desöfteren mit CoffeeScript verglichen wird, macht es Sinn, sich zunächst die Unterschiede und Gemeinsamkeiten zu vergegenwärtigen.

  • Wie TypeScript stellt auch CoffeeScript ein Superset von JavaScript dar. Es wurde zu einer Zeit veröffentlicht, als JavaScript vor allem für seine zahlreichen Unzulänglichkeiten bekannt war. CoffeeScript sollte diese (beziehungsweise einige davon) als eine Art Notlösung beheben. Allerdings entwickelte sich JavaScript im weiteren Verlauf immer weiter - so dass CoffeeScript irgendwann in der Bedeutungslosigkeit verschwand.

  • Civet hingegen ist als Value-Added Layer konzipiert, der kontinuierlich wächst und sich weiterentwickelt, um TypeScript- (und JavaScript-)Code mit modernen Funktionen auszustatten. Wenn Sie die Zusatz-Syntax von Civet austesten möchten, können Sie es - zum Beispiel mit Vite oder esbuild - einfach zu Ihrer Build-Pipeline hinzufügen.

Da Civet direkt zu TypeScript transpiliert, verfügt es über starken Dev-Time-Support in der IDE, wie Civet-Entwickler Erik Demaine erklärt: "Ein wesentlicher Vorteil ist die Language-Server-Protocol-Erweiterung für VS Code, die automatisch TypeScript transpiliert und ausführt, Fehler unterstreicht und eine Hover-Hilfe bietet, während Sie Ihre Datei bearbeiten."

Im Folgenden werfen wir einen Blick auf die wichtigsten Funktionen der Civet-Syntax.

Mit Civet in JSX iterieren

Civet kann JSX verarbeiten. Dabei ermöglicht es Ihnen, Closing Tabs im Markup zu überspringen und schließt diese automatisch, sobald Sie die Tags einrücken. Zudem bündelt es automatisiert mehrere miteinander verwandte Elemente in einem übergeordneten Fragment. Einer meiner größten Pain Points im Zusammenhang mit JSX ist der Umgang mit der Iteration über Listen. Der typische Ansatz besteht darin, JavaScript direkt in das Markup einzuflechten, wie in Listing 1 gezeigt.

Listing 1

<For each={props.items}>

{(item) => {

return (

<li class="item" style={props.style}>

<Item item={item} />

</li>

);

}}

</For>

Das erscheint mir unnötig klobig. Wenn man nur eine Iteration über eine Sammlung durchführen muss, wäre es schön, wenn das einfach und schnell ginge. Listing 2 zeigt den Looper aus Listing 1, geschrieben in Civet.

Listing 2

<For each=props.items>

(item) =>

<li .item {props.style}><Item {item}>

Dieser Code ist deutlich leichter zu verinnerlichen.

Der Civet-Pipe-Operator

Civet stellt Ihnen den vorgeschlagenen TypeScript-Pipe-Operator zur Verfügung, bevor er offiziell wird. Die Grundidee dieses Features: Eine Kombination von Operationen ohne Verschachtelung oder Fluent-Method-Chaining. Wie einst CoffeeScript für JavaScript, können Sie mit Civet die Funktion jetzt nutzen, bevor sie offiziell in TypeScript eingeführt wird.

Die Verwendung des Pipe-Operators (|>) ermöglicht es, verkettete Operationen so zu schreiben, dass sie leicht zu lesen sind. Nehmen wir an, Sie haben mehrere Operationen definiert (etwa foo, bar und baz) und möchten diese nun zusammen verwenden, um eine Variable zu ändern. In reinem JavaScript würden Sie möglicherweise verschachtelte Funktionsaufrufe wie foo(bar(baz(myVar))) oder baz(myNum).bar().foo() erhalten. Beide sind klobig und werden mit zunehmender Komplexität immer schwieriger zu entschlüsseln. Listing 3 zeigt Ihnen, wie Sie die gleiche Logik in Civet mit dem Pipe-Operator ausführen.

Listing 3

let foo = function(){ … }

let bar = function(){ … }

let baz = function(x){ … }

let myVar = "some value";

myVar |> baz |> bar |> foo;

Pattern Matching in Civet

Eine weitere ECMAScript-Funktion, die Sie mit Civet frühzeitig übernehmen können, ist Pattern Matching. Der TC39-Vorschlag, der sich mit den Unzulänglichkeiten des switch-Statements in ECMAScript befassen soll, hat es in sich. Gegenwärtig, so heißt es in dem Vorschlag, enthält switch "eine Fülle von Footguns und mehrdeutiges Scoping". Außerdem mangelt es ihm an Anpassungsmöglichkeiten.

Während der Vorschlag mit match ein neues Keyword einführt, wendet Civet viele der vorgeschlagenen Matching-Verbesserungen direkt auf die switch-Anweisung an. In Civet können Sie beispielsweise auf einen String mit erweitertem Matching umschalten, wie in Listing 4 zu sehen.

Listing 4

let s = [{type:"text", content:"foobar"},'test2'];

switch s

""

console.log "nothing"

/\s+/

console.log "whitespace"

"hi"

console.log "greeting"

[{type: "text", content}, ...rest]

console.log("leading text", content)

// outputs "leading text foobar"

Die switch-Anweisung von Civet ist ziemlich mächtig und geht weit darüber hinaus, Regex-Muster hinzuzufügen.

Loops in Civet

Civet bietet die Möglichkeit, Looping Syntax zu vereinfachen. In Listing 5 wird ein Loop über ein Array mit ganzen Zahlen ausgeführt, um ein neues Array mit deren Quadranten zu erstellen. Der Loop wird in drei Varianten ausgeführt: Civet, programmatisches JavaScript und funktionales JavaScript.

Listing 5

const list =[1,2,3,4,5,6,7];

// Civet

squares :=

for item of list

item * item

// programmatic JS

const squares = (() => {

const results = [];

for (const item of list) {

results.push(item * item);

}

return results;

})();

// functional JS

squares = list.map((x) => { return x*x }));

Single-Argument-Funktionen in Civet

Civet enthält eine "single-argument function shorthand", um (x) => { } zu ersetzen. Listing 6 zeigt eine Reihe von Beispielen - und ihre gewöhnlichen JavaScript-Entsprechungen.

Listing 6

let x = [{name:'test123'},{name:'Another name'}];

console.log(x.map .name);

console.log(x.map &.name?.slice(0,4));

console.log(x.map((x) => x.name));

console.log(x.map((x) => { return x.name?.slice(0, 4)}));

// output is the same in both groups:

[ "test123", "Another name" ]

[ "test", "Anot" ]

Hier sehen Sie, wie Sie ein einzelnes Funktionsargument ohne Klammer und Pfeil deklarieren können. Das kaufmännische Und-Symbol im zweiten Beispiel ermöglicht einen Verweis auf das Argument.

Arrays und Strings in Civet

Civet bringt eine Handvoll Shortcuts mit, um Arrays und Strings aufzuteilen. Es erlaubt Ihnen, eckige Klammern wie Funktionsargumente in einem Array zu verwenden. Die Argumente werden an slice() übergeben, wie Sie es erwarten würden. In Listing 7 führen wir zum Beispiel mehrere Slice-Operationen für eine Zeichenkette durch. Beachten Sie den zusätzlichen Nutzen der Klammern:

Listing 7

let s = "Words are flowing out like endless rain";

console.log(s[10..16]); // outputs "flowing"

// equivalent to console.log(s.slice(10, 1 + 16 || 1 / 0));

console.log(s[-4..]); // output "rain"

// equivalent to console.log(s.slice(-4));

console.log(s[...5]); // outputs "Words"

// equivalent to console.log(s.slice(0, 5));

Konfiguration

Civet enthält eine ganze Reihe von Konfigurationsmöglichkeiten zur Feinabstimmung. Das kann bei der Migration von Projekten hilfreich sein, insbesondere solchen, die CoffeeScript verwenden. Weitere Details finden Sie hier.

Civet-Ressourcen

Wir haben in diesem Artikel nur einige Grundlagen von Civet behandelt - es gibt noch weit mehr zu entdecken. Zum Beispiel hier:

Civet ist vor allem als Ideenlabor nützlich und ein gutes Tool, um mit neuen Funktionen zu experimentieren, die für die ECMAScript-Spezifikation vorgeschlagen werden. (fm)

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Network World.