Description
🚀 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>
:
angular-cli/packages/angular_devkit/schematics/src/engine/interface.ts
Lines 234 to 237 in 37a06a7
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 ofRule
Describe alternatives you've considered
- workaround on my side: return
Promise<Rule | void>
instead ofPromise<Tree>
- workaround on Angular's side: move
rxjs
fromdependencies
topeerDependencies
inpackage.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