TypeScript 3.0 – die Neuerungen

TypeScript 3.0 – das sind die Neuerungen

Avatar von Christopher Stock

Am 30. Juli 2018 wurde TypeScript 3.0 veröffentlicht. Die quelloffene Transpiler-Sprache aus dem Hause Microsoft feiert damit ihr knapp sechsjähriges Bestehen und da ich selbst ein großer Fan von TypeScript bin, möchte ich Euch in diesem Artikel die wichtigsten Neuerungen dieser Version kurz vorstellen.

Projektreferenzen

Unter TypeScript 3.0 können erstmalig externe TypeScript-Projekte über deren eigenständige tsconfig.json-Datei referenziert und somit als Abhängigkeit definiert werden. Über die neue Angabe references in der tsconfig.json kann der Dateipfad externer TypeScript-Projekte angegeben und somit beim Kompilieren des Projektes berücksichtigt werden.

Die folgende Compiler-Config unter frontend/tsconfig.json referenziert die beiden Projekte backend und e2e-test über deren entsprechende tsconfig.json-Files:

{
    "compilerOptions": {

        // all compiler options – as ever

    },

    "references": [
        {
            "path": "../backend"
        },
        {
            "path": "../e2e-test"
        },
    ],
}

Beim Kompilieren eines Projektes werden die eigenen Sourcefiles neu kompiliert. Die Quelldateien der referenzierten Projekte werden nur dann kompiliert, wenn dies erforderlich ist, ansonsten werden nur deren TypeScript Declaration Files (.d.ts) verwendet. Hierdurch werden die Kompilierzeit sowei die IDE-Speichernutzung eines Projektes deutlich optimiert und zudem noch eine logische Trennung des Projektcodes gefördert.

Sinnvoll ist das beispielsweise beim Erstellen eines Microservices und der daraus resultierenden Trennung der TypeScript-Quellcodes in mehrere Projekte wie frontend, backend und test.

Erweiterte Funktionen für Tupel

Tupel sind unter TypeScript bereits seit der Version 1.3 verfügbar. Mit diesem Datentyp kann ein Array definiert werden, dessen Elemente nicht aus einem einzelnen, sondern aus unterschiedlichen Datentypen bestehen können. Der folgende Codeschnipsel demonstriert den Einsatz eines Tupels:

let myFruitBowl: [ string, number ];

// compiles correctly
myFruitBowl = [ 'Apple', 4 ]; // OK

// compilation fails here
myFruitBowl = [ 4, 'Apple' ];

Ab der Major-Version 3 bietet TypeScript nun ein paar ausgewählte neue Funktionalitäten für diesen Datentyp an:

Rest-Parameter für Tupel

Als Datentyp für Rest-Parameter war bisher lediglich ein Array zulässig. Der folgende Codeschnipsel demonstriert kurz und bündig den Einsatz eines Rest-Parameters:

function myFunction( ...args:number[] ) : void
{
    console.log( 'Number of args: [' + args.length + ']' );
}

myFunction( 0, 1, 2, 3, 4 ); 

// output is: 'Number of args: [5]'

Nun ermöglicht TypeScript 3.0 auch den Einsatz des Tupel-Datentyps als Rest-Parameter für Funktionen. Die folgenden beiden Funktionen sind somit ab sofort äquivalent:

function myFunctionA( ...args: [ number, string, boolean ] ) : void
{
}

function myFunctionB( args_0: number, args_1: string, args_2: boolean ) : void
{
}

Spread-Expressions für Tupel

Analog zur Unterstützung des Tupel-Datentyps als Rest-Parameter einer Funktion kann dieser Typ nun auch als Spread-Expression beim Aufrufen einer Funktion angegeben werden.

Die folgenden drei Aufrufe von myFunctionA sind daher äquivalent:

const args: [ number, string, boolean ] = [ 42, "hello", true ];

// all invocations are equivalent
myFunctionA( 42, "hello", true );
myFunctionA( args[ 0 ], args[ 1 ], args[ 2 ] );
myFunctionA( ...args );

Optionale Tupel-Parameter

Ab TypeScript 3.0 können Parameter eines Tupels auch mittels der ?-Notation als optional gekennzeichnet werden. Somit quittiert der TypeScript-Compiler das Ausbleiben eines Parameters nicht mehr als Fehler:

let myTuple: [ number, string?, boolean? ];

myTuple = [42, "hello", true];
myTuple = [42, "hello"];
myTuple = [42];

Da ich ein Verfechter von sprechendem Code und dem Clustern zusammengehöriger Felder und Informationen in sprechende Klassen und Schnittstellen bin, kann ich von der Verwendung von Tupeln nur abraten. Trotzdem begegnet einem in der Praxis und in bestimmten Anwendungsfällen dieses Konstrukt hin und wieder, weswegen es nicht schaden kann, die Einsatzmöglichkeiten und Vorkommnisse dieses Features zu kennen.

Neuer Datentyp “unknown“

Neben den wichtigsten grundlegenden Datentypen boolean, number, string, undefined, any und null bietet TypeScript ab Version 3.0 den neuen Datentyp unknown an. Dieser stellt das typsichere Äquivalent zu dem nicht-typsicheren Datentyp any dar. Einer Variable vom Typ unknown können Werte aller beliebiger Datentypen zugewiesen werden, für den umgekehrten Vorgang bedarf es aber einer expliziten Typisierung.

Der folgende Code unter Einsatz des Datentyps any kompiliert korrekt:

let myAny    :any    = 42;
let myNumber :number = myAny;

Der selbe Code unter Einsatz des Datentyps unknown wirft beim Kompilieren einen Fehler:

let myUnknown :unknown = 42;
let myNumber  :number  = myUnknown;

Zum Fixen des Compilerproblems muss eine explizite Typisierung angegeben werden:

let myUnknown :unknown = 42;
let myNumber  :number  = myUnknown as number;

Der Datentyp unknown bietet sich besonders für Portierungen von (untypisiertem) JavaScript-Code nach TypeScript an und bietet dabei einen höheren Pragmatismus.

Unterstützung für “defaultProps“ in JSX-Elementen

Der Einsatz des statischen Feldes defaultProps innerhalb von React-Komponenten wird nun auch im TypeScript-Code unterstützt.

Die folgende React-Komponente src/de/mayflower/tasklist/components/Greet.tsx kann verwendet werden, ohne dabei Properties in Form von Attributen zu übergeben. In diesem Falle werden die Properties aus dem statischen Feld defaultProps zugewiesen:

export interface Props
{
    name: string;
}

export class Greet extends React.Component<Props> 
{
    static defaultProps = { name: "world"};

    render() {
        const { name } = this.props;
        return <div>Hello ${name.toUpperCase()}!</div>;
    }
}

// Type-checks! No type assertions needed!
let el = <Greet />

Neue Referenzanweisung für built-in Libs

Mit der folgenden Angabe kann dem Compiler eine weitere TypeScript-Quelldatei an der angegebenen Stelle inkludiert werden. Auch kann durch diese Anweisung die explizite Reihenfolge der zu kompilierenden Dateien festgelegt werden.

/// <reference path="src/de/mayflower/util/MathUtil.ts" />

Nun kann über diese neue Referenzanweisung eine built-in Lib angegeben werden, sodass sie der Compiler beim Kompilieren berücksichtigt und die hierdurch zur Verfügung gestellten Funktionalitäten erkennt. Im folgenden Beispiel wird die String-Funktion padStart( size ) ermöglicht, die ohne die Angabe der neuen Referenzanweisung nicht gefunden würde.

/// <reference lib="es2017.string" />

console.log( 'Left padded foo: [' + ( 'foo'.padStart( 10 ) ) + ']' );

// Left padded foo: [       foo]

Diese Angabe ist äquivalent zur Verwendung der Compiler-Option

--lib es2017.string

Unter Verwendung von Webpack sind diese Referenzanweisungen allerdings obsolet, da hier mit dem Schlüsselwort import sowie mit lib-Angaben in der webpack.config.js gearbeitet werden sollte.

TypeScript 3.0

Unterm Strich sind die Änderungen der neuen Major-Version 3.0 überschaubar. Besonders löblich ist für mich die Tatsache, dass TypeScript 3.0 mit so gut wie gar keinen Breaking Changes daherkommt und einige neue Konzepte und Ideen bereithält.

Für fachliche Rückfragen und Anregungen stehe ich Euch wie immer gerne unter christopher.stock@mayflower.de zur Verfügung.

Avatar von Christopher Stock

Kommentare

6 Antworten zu „TypeScript 3.0 – das sind die Neuerungen“

  1. TypeScript 3.0 – das sind die Neuerungen https://t.co/887FkPMRd2 via @mayflowergmbh

  2. Was sind die Neuerungen in #typescript 3? Unser @jenetic1980 hat sich die Sache etwas genauer angesehen: https://t.co/EjTd017cdo

  3. Was die Neuerungen in #typescript 3 bedeuten lest ihr hier: https://t.co/EjTd01oN4W

  4. Interessiert ihr euch für die Neuerungen rund um #typescript 3? Unser @jenetic1980 hat sie sich angesehen und für e… https://t.co/z8An46gIqJ

  5. Wollt ihr wissen, was es mit den Neuerungen in #typescript 3 auf sich hat? @jenetic1980 hat sie sich genauer angese… https://t.co/fPMXm9qRde

  6. Ihr habt euch noch nicht mit #typescript 3 beschäftigt? Dann wird es aber Zeit: https://t.co/EjTd01oN4W

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.