ember-cli-typescript
ember-cli-typescript copied to clipboard
Registries should live in individual files
Because module dependencies are simply build up iteratively (and as a DAG), TS often ends up in a scenario where it doesn't yet know the way to resolve a given e.g. service('session')
call. (This may be the underlying problem in #119.)
The solution is:
- Create a single registry file for each of all the services/controllers/etc. in the app; import and add them to the registry all there.
- In
my-app/
. Import all addons that declare services and if they don't register themselves in their own type definition, register them in (1). - Add imports for all the registries in the
my-app/index.d.ts
;
File system:
root/
types/
my-app/
registry/
services.d.ts
controllers.d.ts
ember-data/
models.d.ts
adapters.d.ts
serializers.d.ts
Example my-app/index.d.ts
(with the not-yet-upstreamed 😬 types for ember-freestyle):
// For type registry resolution
import 'ember-freestyle/services/freestyle';
import './registry/controllers';
import './registry/services';
import './registry/ember-data/adapters'
import './registry/ember-data/models'
import './registry/ember-data/serializers'
To make this work, we need to:
- update the existing generators not to include the registries
- use the
afterInstall
hook to either add to the existing registries if they exist; or add and import them into the root typings folder and then add them to the registry if they don't
I'm trying to setup a registry for a model but tsc isn't resolving the class for the model in the registry, for example:
// app/models/organization.ts
import DS from 'ember-data';
export default class Organization extends DS.Model.extend({
orgName: DS.attr('string'),
orgAddress: DS.attr('string')
}) {}
// types/my-app/registry/models.d.ts
import Organization from 'my-app/models/organization'
declare module "ember-data" {
interface ModelRegistry {
organization: Organization;
}
}
Says it can't find 'my-app/models/organization' but the same import call works in other parts of the app so I think it must be because it is in the module declaration files, and if I leave that out it can't resolve Organization as a type.
I can "fix" this by adding the class declaration, but not sure if this is the correct approach:
// types/my-app/registry/models.d.ts
declare class Organization{}
declare module "ember-data" {
interface ModelRegistry {
organization: Organization;
}
}
Another "fix" is to use the absolute path in the import, so something about module resolution seems to be different when dealing with module declaration files.
I'd like what I'm doing to be compatible with what you are going to do with the generators later, any direction you can give would help. Thanks!
@sdhawley is this in a public repository? If not, do you think you could put together a reproduction?
Not a public repo, I'll see if I can replicate it in a fresh ember app.
@sdhawley also just to check: when you have that registry set up, are you importing it anywhere?
@chriskrycho, no I didn't import it anywhere. I'm just seeing the warning in vscode that it is not able to resolve the import within models.d.ts.
@dwickern I've setup a fresh example repo https://github.com/sdhawley/example.git that shows the same behavior. The model is 'some-model'.
I'm no longer sure this is the case – I've seen things "just work" in a number of scenarios since I opened it. I'd still like to see if I can reproduce the original problem at some point. @sdhawley, have you seen it crop up again since February?
Haven't run into this problem, I think now that the blueprint puts the registry in the model file
I believe this is now resolved—not least because we did actually update the blueprints to do this (and I just forgot to close it, years ago).