Skip to content

Rule from @angular-devkit/schematics should accept return type Promise<Tree> #22783

Closed
@Platonn

Description

@Platonn

🚀 Feature request

Rule from @angular-devkit/schematics should accept return type Promise<Tree>

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc
  • other: compiling custom schematics that depend on @angular-devkit/schematics

Description

The interface Rule from @angular-devkit/schematics should accept the return type Promise<Tree> for asynchronous schematics. Now it only accepts Observable<Tree>:

export type Rule = (
tree: Tree,
context: SchematicContext,
) => Tree | Observable<Tree> | Rule | Promise<void | Rule> | void;

The current problem with Rule accepting only Observable<Tree> it that it accepts only the Observable from rxjs of a fixed version 6.6.7 (at the moment of writing) which is hardcoded in dependencies in package.json of @angular-devkit/schematics:

Therefore, if I'm writing custom schematics in my repo, while having any slightly different version of rxjs installed, e.g. 6.6.3, then I get an error about incompatible variants of the interface Subscriber - between my installed version in node_modules and the fixed version from node_modules/@angular-devkit/core/node_modules/rxjs (which is derived from the interface Rule)

Example of custom schematics for minimal reproduction:

import { Rule, Tree } from '@angular-devkit/schematics';
import { of } from 'rxjs';

export function migrate(): Rule {
  return (tree: Tree) => {
    return of(tree);
  };
}

The error message in detail:

(parameter) _context: SchematicContext
Type '(tree: Tree, _context: SchematicContext) => Observable<Tree>' is not assignable to type 'Rule'.
  Type 'Observable<Tree>' is not assignable to type 'void | Rule | Tree | Observable<Tree> | Promise<void | Rule>'.
    Type 'import("/Users/krzysztof/code/develop-ng13/node_modules/rxjs/internal/Observable").Observable<import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/schematics/src/tree/interface").Tree>' is not assignable to type 'import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/core/node_modules/rxjs/internal/Observable").Observable<import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/schematics/src/tree/interface").Tree>'.
      The types of 'source.operator.call' are incompatible between these types.
        Type '(subscriber: import("/Users/krzysztof/code/develop-ng13/node_modules/rxjs/internal/Subscriber").Subscriber<any>, source: any) => import("/Users/krzysztof/code/develop-ng13/node_modules/rxjs/internal/types").TeardownLogic' is not assignable to type '(subscriber: import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/core/node_modules/rxjs/internal/Subscriber").Subscriber<any>, source: any) => import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/core/node_modules/rxjs/internal/types").TeardownLogic'.
          Types of parameters 'subscriber' and 'subscriber' are incompatible.
            Type 'import("/Users/krzysztof/code/develop-ng13/node_modules/@angular-devkit/core/node_modules/rxjs/internal/Subscriber").Subscriber<any>' is not assignable to type 'import("/Users/krzysztof/code/develop-ng13/node_modules/rxjs/internal/Subscriber").Subscriber<any>'.
              Property 'isStopped' is protected but type 'Subscriber<T>' is not a class derived from 'Subscriber<T>'.

Describe the solution you'd like

  • expose Promise<Tree> as a return type of Rule

Describe alternatives you've considered

  • workaround on my side: return Promise<Rule | void> instead of Promise<Tree>
  • workaround on Angular's side: move rxjs from dependencies to peerDependencies in package.json of @angular-devkit/schematics and relax the version to ^6.6.0 (but still.. what if somebody is using rxjs7 in their repo?)
  • I'm opened to your other suggested ideas or workarounds

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions