2016-11-15 14 views
2

TypeScriptで深くネストされた配列を記述する型またはインターフェイスを定義するにはどうすればよいですか?TypeScriptに深くネストされた配列を記述する

たとえば、任意の数のパターンに対してパスをテストする関数を作成しているとします。

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

Matcher型は、以下のいずれかであってもよい:すなわち

  • string
  • RegExp
  • Matcher[](自己参照に注意)

、コンパイラは以下を受け入れるべきです:

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!!! 

活字体でこれを達成するための方法はありますか?

答えて

2

はい、これはTypeScriptで実行できます。ソリューションは少し冗長ですが、 ジェネリック型エイリアスとインターフェイスの組み合わせを使用して解決できます。

深くネストされた配列を定義するインタフェースから始めます。

type Matcher = DeepArray<string | RegExp>; 

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

しかし、問題は、関数が、単一stringまたはRegExpを受け入れる必要があることを指定:

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

これまでのところ、コンパイラは以下を受け付けます。この は引き続きコンパイラエラーを生成します。

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

私たちは、ジェネリック型の別名で、この問題を解決することができます。

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

そして今、予想通り、私たちのタイプは動作します。

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!!! 
関連する問題