You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0800-ts-adoption-plan.md
+19-25Lines changed: 19 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -541,36 +541,42 @@ For the classic DI system, we no longer require (or benefit from) string key-bas
541
541
}
542
542
```
543
543
544
-
With the introduction of full support for native classes and decorators in Octane, there is no need for this (and it was rather janky to begin with!). Accordingly, we will simply remove support for these two type registries entirely:
544
+
With the introduction of full support for native classes and decorators in Octane, and given the current status of the decorators implementation in TypeScript, this does not provide type inference. However, these kinds of type registries can still provide two benefits for consumers:
545
545
546
-
- The service `Registry` in `@ember/service`
547
-
- The controller `Registry` in `@ember/controller`
546
+
1. When renaming a service injection, like `@service('session') sessionService;`, or using its full name, like `@service('shared@session') session;`, the registry can still check that the resolved name is one that is registered.
548
547
549
-
The decorators will continue to accept a string key, but will not validate that against a registry, since decorators cannot change the types of the items they decorator in TypeScript.[^reintroduce]
548
+
2. It can be used with the other things in the DI system, e.g. making `Owner.lookup('service:session')` type safe, and thereby making things like `this.owner.lookup('service:session')` in tests automatically be well-typed.
550
549
551
-
For Ember Data, there is considerably more ongoing need for registry-style APIs. `Store.findRecord` isn’t going anywhere any time soon, for example, and it *requires* some kind of registry to make `this.store.findRecord('user', 1)` correctly return a `User` model. Many other APIs within Ember Data similarly require registries for type safety. Thus, Ember Data will need its own dedicated design for handling those, and this RFC leaves those for the Ember Data team to address in a dedicated RFC.
550
+
The `@service` decorator will therefore continue to accept a string key, and will validate that against a registry, even though decorators cannot change the types of the items they decorate in TypeScript today. Additionally, the registry will be integrated into `Owner` types so that it can be used more generally. Moreover, the design for an `Owner` registry should allow others to integrate in the same way.
551
+
552
+
Controller injection, by contrast with service injection, is decreasingly used across the ecosystem and not generally recommended, and we expect it to be deprecated during Ember v6. Accordingly, we will *keep* support for the service registry while dropping support for the controller registry. (Given an appropriate design for `Owner`, end users could reimplement this if they so chose.)
552
553
553
-
[^reintroduce]: We could conceivably reintroduce a registry of this form in the future if that limitation on decorators in TypeScript changes, so that `@service('session') declaresession;` would have the right type without needing an explicit type annotation, but that would need to be well-motivated on the merits, and there are actually advantages to having explicit type imports for the static analyzability of the code. The combination of Embroider and other future design moves we might make for the design system, for example [this experiment by pzuraq](https://github.com/pzuraq/ember-totally-not-module-based-services), may make other directions more appealing than the registry approach.
554
+
Future designs for services and dependency injection more generally will need to be written to account for the capabilities of TypeScript’s implementation of Stage 3 decorators as they grow and change over time.
555
+
556
+
For Ember Data, there is considerably more ongoing need for registry-style APIs. `Store.findRecord` isn’t going anywhere any time soon, for example, and it *requires* some kind of registry to make `this.store.findRecord('user', 1)` correctly return a `User` model. Many other APIs within Ember Data similarly require registries for type safety. Thus, Ember Data will need its own dedicated design for handling those, and this RFC leaves those for the Ember Data team to address in a dedicated RFC.
554
557
555
558
556
559
### CLI Integration
557
560
558
561
We will introduce a new `--typescript` (`-ts`) flag for the `embernew` and `emberaddon` commands, allowing users to opt into TypeScript when generating a new project. Using this flag will:
559
562
560
-
- Install Ember TypeScript integration tooling, today consisting simply of `ember-cli-typescript` and its generators.
561
563
- Set the `isTypeScriptProject` option for `.ember-cli` (introduced in [RFC #0776][rfc-0776]) to `true`, so that blueprints are generated with TypeScript by default in the project.
562
564
- Configure linting:
563
565
- In the`.eslintrc.js` blueprint:
564
-
- use `@typescript-eslint/parser` instead of the Babel ESLint parser
565
-
- include `@typescript-eslint` in the `plugins` key
566
-
- include `plugin:@typescript-eslint/recommended` in the `extends` key
567
-
- Install the `@typescript-eslint` dependencies instead of of the Babel ESLint dependencies in `package.json`
566
+
- Use `@typescript-eslint/parser` instead of the Babel ESLint parser.
567
+
- Include `@typescript-eslint` in the `plugins` key.
568
+
- Include `plugin:@typescript-eslint/recommended` in the `extends` key.
569
+
- Install the `@typescript-eslint` dependencies instead of, or in addition to (as appropriate), the Babel ESLint dependencies in `package.json`.
570
+
- Configure [Glint][glint] for type checking and, for addons, emitting type declarations during build.
571
+
- Create `tsconfig.json` files and generate their `compilerOptions.paths`.
572
+
- Configure `ember-cli-babel` to include the TypeScript transform. (This may just be an “out of the box” setting so it always works and does not require configuration!)
573
+
- Set up packages with scripts to do type checking and, in the case of v1 addons, emitting type declarations using `glint`.
We will also update the Glimmer Component blueprint in the Ember.js repo to include [the component’s signature][rfc-0748], so that it can be used by TypeScript.
572
578
573
-
We will *not* be eliminating`ember-cli-typescript` as part of this process, because it remains a useful home for some of the tooling, and may remain a useful configuration point in the future, for example when we incorporate [Glint][glint] into official Ember tooling. In this design, only the pieces which are *necessarily* shared will be hoisted into`ember-cli` itself, with the other pieces remaining in `ember-cli-typescript`. For example, the blueprint for generating `tsconfig.json` files should remain in `ember-cli-typescript`.
579
+
We will be sunsetting`ember-cli-typescript` as part of this process. It was a valuable and needful part of the ecosystem when we did *not* have official support, but now it duplicates other sources of configuration and tooling, making maintenance needlessly more complicated. All of its capabilities can be managed more cleanly in other projects:`ember-source` and other addons can ship blueprints which support both TypeScript and JavaScript, `ember-cli-babel` and other build tools can manage transpilation, and `glint` supports end-to-end type checking.
@@ -824,16 +830,4 @@ This would be a reasonable approach—and was in fact what the other Typed Ember
824
830
825
831
## Unresolved questions
826
832
827
-
- How should we support opting into TypeScript support after starting a project? Today, users do this by running `ember install ember-cli-typescript` and getting its updates to blueprints etc.—but that will not be as obvious in this design, and even if we continue to use that as the mechanism, we need to document it and decide which parts `ember-cli-typescript` is responsible for and which it is not.
828
-
829
-
- Which, if any, blueprints need to be updated besides the Glimmer Component blueprint, in the absence of type registries for Service and Controller classes?
830
-
831
-
- Did we miss any Classic features for which we need to specify what we will and will not provide?
832
-
833
-
- Should we ship an `ember-ultra-strict` mode initially, and if so what additional flags should it include?
834
-
835
-
- Is specifying Ember Data’s registries a blocker for adopting this RFC?
836
-
837
-
- Do we need an appendix to this RFC specifying user-constructibility and import location for existing interfaces like `Transition` and `RouteInfo`?
838
-
839
-
- Should we do the work to introduce a “simplified” presentation of the types for JavaScript users in our API docs, which (for example) removes generics and replaces `unknown` with `any` or similar, to avoid requiring JavaScript users to understand those TypeScript details?
0 commit comments