【问题标题】:Describe a deeply nested array in TypeScript在 TypeScript 中描述一个深度嵌套的数组
【发布时间】:2017-03-28 22:03:26
【问题描述】:

如何在 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!!!

有没有办法在 TypeScript 中实现这一点?

【问题讨论】:

    标签: arrays typescript types interface nested


    【解决方案1】:

    是的,您可以在 TypeScript 中执行此操作。解决方案有点冗长,但可以使用 泛型类型别名和接口的组合。

    从定义深度嵌套数组的接口开始。

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

    到目前为止,编译器将接受以下内容:

    type Matcher = DeepArray<string | RegExp>;
    
    const m1: Matcher = ['src/**/*', /\.js$/];
    const m2: Matcher = ['src/**/*', [/\.js$/, ['*.ts']]];
    

    但问题指定该函数还应接受单个stringRegExp。这 仍然会产生编译器错误。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      • 2019-04-17
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2023-03-09
      相关资源
      最近更新 更多