Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
1 of 16 tasks
Platonn opened this issue Mar 1, 2022 · 4 comments · May be fixed by #29311
Open
1 of 16 tasks

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

Platonn opened this issue Mar 1, 2022 · 4 comments · May be fixed by #29311
Labels
area: @angular-devkit/schematics feature: under consideration Feature request for which voting has completed and the request is now under consideration type: bug/fix
Milestone

Comments

@Platonn
Copy link
Contributor

Platonn commented Mar 1, 2022

🚀 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
@alan-agius4 alan-agius4 added area: @angular-devkit/schematics feature Issue that requests a new feature labels Mar 1, 2022
@ngbot ngbot bot added this to the needsTriage milestone Mar 1, 2022
@angular-robot angular-robot bot added the feature: votes required Feature request which is currently still in the voting phase label Mar 2, 2022
@angular-robot
Copy link
Contributor

angular-robot bot commented Mar 2, 2022

This feature request is now candidate for our backlog! In the next phase, the community has 60 days to upvote. If the request receives more than 20 upvotes, we'll move it to our consideration list.

You can find more details about the feature request process in our documentation.

@shaharkazaz
Copy link

shaharkazaz commented Mar 19, 2022

I'm currently working rxjs 7.5+ and my schematics build broke because of this dependency.
It should have the rxjs peerDependency which supports both v6 and v7:

  "peerDependencies": {
    "rxjs": "^6.5.3 || ^7.4.0",
    "zone.js": "~0.11.4"
  },

Taken from @angular/[email protected] package.json

@angular-robot
Copy link
Contributor

angular-robot bot commented Apr 10, 2022

Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

Find more details about Angular's feature request process in our documentation.

@angular-robot angular-robot bot added feature: under consideration Feature request for which voting has completed and the request is now under consideration and removed feature: votes required Feature request which is currently still in the voting phase labels Apr 11, 2022
@dgp1130
Copy link
Collaborator

dgp1130 commented Aug 11, 2022

Taking a quick look at this, it seems that the problem is more with mismatch between the schematics' Observable type and the @angular-devkit/schematics Observable return type. Proper solution is probably to convert the return type to use Subscribable<T>, and separately we should maybe look into finding ways to dedupe RxJS dependencies in the project.

@dgp1130 dgp1130 added type: bug/fix and removed feature Issue that requests a new feature labels Aug 11, 2022
alan-agius4 added a commit to alan-agius4/angular-cli that referenced this issue Jan 9, 2025
…ing a `Promise` of `Tree`

The `Rule` type has been updated to align with its intended functionality, allowing it to return a `Promise<Tree>`. Previously, this behavior was supported but not properly typed.

Closes angular#22783
alan-agius4 added a commit to alan-agius4/angular-cli that referenced this issue Jan 9, 2025
…ing a `Promise` of `Tree`

The `Rule` type has been updated to align with its intended functionality, allowing it to return a `Promise<Tree>`. Previously, this behavior was supported but not properly typed.

Closes angular#22783
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: @angular-devkit/schematics feature: under consideration Feature request for which voting has completed and the request is now under consideration type: bug/fix
Projects
None yet
4 participants