These types were written by the team at https://www.skylight.io/, specifically @gitKrystan (with lots of help from @chancancode).
Gist filenames don't allow slashes, so I replaced them with :
.
Add "<app-name>/mirage/*": ["mirage/*"]
to your paths config in your tsconfig.json
The MirageJS types expect you to create a registry of Mirage Models and Factories for Mirage's string key lookups (e.g. this.server.create('user');
. The registered Mirage Models will be used for determining relationship types, and the Factories for determining attribute types.
When using ember-cli-mirage, Mirage will automatically discover your models and their relationships, so you don’t need to define any files within Mirage yourself. Unfortunately, the MirageJS types appear to expect Mirage models to be explicitly defined. This gist provides a ConvertModelRegistry
utility type to convert the ModelRegistry
provided by ember-cli-typescript into an interface of Mirage ModelDefinition
s for use in the Mirage Registry.
See mirage:registry.ts
below for an example Mirage Registry.
The Mirage Registry will extract attribute types from your Mirage Factories. But sometimes the default factory value types don't encompass all of the valid types for that attribute.
For example, imagine you have this User Factory:
// mirage/factories.user.ts
import { Factory } from 'ember-cli-mirage';
export default Factory.extend({
fullName: 'Test (development) Shared',
githubUsername: null,
});
The Mirage Registry will extract something like:
interface UserAttrs {
fullName: string;
githubUsername: null;
}
And something like this.server.create('user', { githubUsername: 'gitKrystan' });
will result in a type error.
To account for this, mirage:factories:types:attr.ts
provides types for each of the Ember transforms, plus an attribute
function for arbitrary attributes and a nullable
function for nullable attributes.
// mirage/factories.user.ts
import { Factory } from 'ember-cli-mirage';
import { booleanAttr, stringAttr, StringAttr, nullable } from './types/attr';
export default Factory.extend({
fullName: stringAttr('Test (development) Shared'),
githubUsername: nullable(stringAttr),
});
And now the extracted interface will look something like:
interface UserAttrs {
fullName: string;
githubUsername: string | null;
}
See mirage:factories:user.ts
below for an example Factory.
Declare this: MirageTestContext
to let TypeScript know you expect to have access to this.server
in your test.
See tests:acceptance:my-acceptance-test.ts below.
We've noticed that our Mirage types can be noticeably slow to compile. We suspect this is due to the work required to instantiate the Mirage Registry:
- In order to create the registry, the Mirage types have to create all of the relevant model and factory types.
- Relationships can cause circular references. For example, if a user has many blog posts and each blog post has a user, does TypeScript instantiate the Post and User types many times?
Mirage adds a key to the Schema
object for each of your models (e.g. this.server.schema.users
) with a value of the DbCollection
for that model. Unfortunately, these keys are not represented in the Mirage types, and doing so would be difficult because the Mirage registry keys are singular (e.g. 'user'
) while the Schema keys are plural (e.g. 'users'
).
Instead, I recommend using alternative string-key lookup methods on the Mirage Schema
object directly. For example:
// before:
// Type-checking error: Property `users` does not exist on type `Schema`
this.server.schema.users.find(1);
// after:
this.server.schema.find('user', 1);
- Mirage types: https://github.com/miragejs/miragejs/blob/master/types/index.d.ts
- Salsify's Mirage types: https://gist.github.com/dfreeman/33fc80164c0ad91d5e9480a94aa6454c
- Center for Open Science's Mirage types: https://github.com/CenterForOpenScience/ember-osf-web/tree/develop/types/ember-cli-mirage
Thanks a lot! These types work great for me