问题
How do I define a type or interface describing a deeply nested array in TypeScript?
For example, let's say I am writing a function for testing a path against any number of patterns.
function match(path: string, matcher: Matcher): boolean { /* ... */ }
The Matcher
type may be any of the following:
string
RegExp
Matcher[]
(note the self-reference)
In other words, the compiler should accept the following:
match('src/index.js', 'lib/**/*');
match('src/index.js', /\/node_modules\//);
match('src/index.js', ['src/**/*', /\.js$/]);
match('src/index.js', ['src/**/*', [/\.js$/, ['*.ts']]]);
But the following should produce a compiler error:
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!!!
Is there a way to achieve this in TypeScript?
回答1:
Yes, you can do this in TypeScript. The solution is a bit verbose, but it can be done using a combination of generic type aliases and interfaces.
Start with an interface defining a deeply nested array.
interface DeepArray<T> extends Array<T | DeepArray<T>> { }
So far, the compiler will accept the following:
type Matcher = DeepArray<string | RegExp>;
const m1: Matcher = ['src/**/*', /\.js$/];
const m2: Matcher = ['src/**/*', [/\.js$/, ['*.ts']]];
But the question specifies that the function should also accept a single string
or RegExp
. This
will still produce a compiler error.
const m3: Matcher = 'lib/**/*'; // Compiler Error!!!
const m4: Matcher = /\/node_modules\//; // Compiler Error!!!
We can solve this problem with a generic type alias:
type Deep<T> = T | DeepArray<T>;
And now our type works as expected.
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!!!
来源:https://stackoverflow.com/questions/40602784/describe-a-deeply-nested-array-in-typescript