2016-11-15 8 views
2

Wie definiere ich einen Typ oder eine Schnittstelle, die in TypeScript ein tief verschachteltes Array beschreiben?Beschreiben eines tief verschachtelten Arrays in TypeScript

Nehmen wir zum Beispiel an, ich schreibe eine Funktion zum Testen eines Pfades gegen eine beliebige Anzahl von Mustern.

function match(path: string, matcher: Matcher): boolean { /* ... */ } 

Der Matcher Typ kann einer der folgenden sein:

  • string
  • RegExp
  • Matcher[] (beachten Sie die Selbstreferenz)

Mit anderen Worten, die Der Compiler sollte folgendes akzeptieren:

match('src/index.js', 'lib/**/*'); 
match('src/index.js', /\/node_modules\//); 
match('src/index.js', ['src/**/*', /\.js$/]); 
match('src/index.js', ['src/**/*', [/\.js$/, ['*.ts']]]); 

aber die folgenden sollte einen Compiler-Fehler erzeugen:

match('src/index.js', {'0': 'src/**/*'});    // Compiler Error!!! 
match('src/index.js', ['src/**/*', true]);    // Compiler Error!!! 
match('src/index.js', ['src/**/*', [/\.js$/, [3.14]]]); // Compiler Error!!! 

Gibt es eine Möglichkeit, dies zu erreichen in Typoskript?

Antwort

2

Ja, Sie können dies in TypeScript tun. Die Lösung ist ein wenig ausführlich, aber es kann eine Kombination von generischen Typ-Aliasen und Schnittstellen verwendet werden.

Beginnen Sie mit einer Schnittstelle, die ein tief verschachteltes Array definiert.

type Matcher = DeepArray<string | RegExp>; 

const m1: Matcher = ['src/**/*', /\.js$/]; 
const m2: Matcher = ['src/**/*', [/\.js$/, ['*.ts']]]; 

Aber die Frage gibt an, dass die Funktion auch eine einzelne string oder RegExp annehmen sollte:

interface DeepArray<T> extends Array<T | DeepArray<T>> { } 

Bisher wird der Compiler die folgende akzeptieren. Dieser wird weiterhin einen Compiler-Fehler erzeugen.

const m3: Matcher = 'lib/**/*';   // Compiler Error!!! 
const m4: Matcher = /\/node_modules\//; // Compiler Error!!! 

Wir können dieses Problem mit einem Alias ​​gattungsgemäßen Art lösen:

type Deep<T> = T | DeepArray<T>; 

Und jetzt unsere Art wie erwartet funktioniert.

type Matcher = Deep<string | RegExp>; 

function match(path: string, matcher: Matcher): boolean { /* ... */ } 

match('src/index.js', 'lib/**/*'); 
match('src/index.js', /\/node_modules\//); 
match('src/index.js', ['src/**/*', /\.js$/]); 
match('src/index.js', ['src/**/*', [/\.js$/, ['*.ts']]]); 

match('src/index.js', {'0': 'src/**/*'});     // Compiler Error!!! 
match('src/index.js', ['src/**/*', true]);    // Compiler Error!!! 
match('src/index.js', ['src/**/*', [/\.js$/, [3.14]]]); // Compiler Error!!! 
Verwandte Themen