In my ember.js project, I type check javascript files with Typescript and the checkJs option.
Here is a simple route.js
file example
import Route from '@ember/routing/route';
export default class UsersRoute extends Route {
model() {
return this.store.findAll('user');
}
}
With this code, I get the following Typescript error
route.js:5:31 - error TS2345: Argument of type '"user"' is not assignable to parameter of type 'never'.
5 return this.store.findAll('user');
~~~~~~
The ember-data type definitions are provided by the @types/ember-data package, and here is the findAll definition
findAll<K extends keyof ModelRegistry>(
modelName: K,
options?: {
reload?: boolean;
backgroundReload?: boolean;
include?: string;
adapterOptions?: any;
}
): PromiseArray<ModelRegistry[K]>;
This is how far I could go while investigating how findAll
was defined.
In theory, this.store.findAll('user');
is valid, but what should I do to fix this Typescript error?
To understand what's happening I recommend reading this section of the ember-cli-typescript docs. The gist is that the types supplied for Ember do some extra work to make it so that when you type this.findRecord('person', 1)
, the thing you get back is a Person
(e.g. the DS.Model
you've defined). To make that work, the types define a "registry"—a mapping between the string name and the type to return. That "registry" being empty is the problem you're seeing in the types.
The default configuration with ember-cli-typescript makes this "just work", by setting up the paths
key in tsconfig.json
to include "*": "types/*"
and including this file at <your app directory>/types/ember-data/types/registries/model.d.ts
:
/**
* Catch-all for ember-data.
*/
export default interface ModelRegistry {
[key: string]: any;
}
That makes all string lookups for models "work" by just making the type be any
.
If you want to actually define types, you'll need to create a user.d.ts
file located right next to the user.js
which exports the model type and which includes this:
declare module 'ember-data/types/registries/model' {
export default interface ModelRegistry {
'user': User;
}
}
Running ember generate ember-cli-typescript
if you're already using it will update these things for you. You can also manually create that file with those contents and set up the paths
mapping (and you may want to add the other paths mappings from the default blueprint as well).