-
Notifications
You must be signed in to change notification settings - Fork 12
[DRAFT!!!] QUEST: Let's type the Ember.js ecosystem! #14
Comments
Has any work been done on ember-simple-auth? I'm getting complaints when building:
|
@sdhawley not to my knowledge! This quest will be kicking off properly in the next week or two. |
We'd welcome your going after that, and happy to mention in |
I've started creating an ember-simple-auth.d.ts locally as I run into things, happy to share it. |
Please do! |
Regarding |
That’s correct; they’re already done. I’ll update this just before I post the final version and announce it (including updating the actual list! This is 9 months out of date).
|
Update: mostly correct—the one thing |
Closing in favor of typed-ember/ember-cli-typescript#48 – the original! |
*DRAFT – STILL WORKING OUT THE DETAILS HERE! DO NOT JUMP IN JUST YET!
Let’s type the Ember.js ecosystem!
Overview
The goal of this quest issue is to write TypeScript type definitions to cover the top 100 addons listed on Ember Observer as of the time the quest is launched. Our bonus goal is to type any other addons which want to participate, as well!
Philosophy
There are two overarching concerns that drive everything else in this quest:
Good type definitions are worth their weight in gold. Bad type definitions are worse than no type definitions at all. Accordingly, our goal is not just to get some type definitions written, but to write good type definitions that actually give us these benefits, and which don’t mislead us or give us a false sense of security.
We should be good citizens of the Ember.js community. We want to use TypeScript to be helpful; we do not want to be pushy jerks or typed-language fanatics. As part of the Ember.js ecosystem, we’re all in this together, and those of us working on the TypeScript side should never look down on people who prefer JavaScript – there are legitimate tradeoffs either direction. So, as always, let’s be kind!
Improving developer experience for all Ember.js users
By doing this, we can make the experience of developing Ember apps better for everyone – not just TypeScript users, but all the people using plain-old JavaScript as well. An increasing number of editors will take advantage of TypeScript type definitions if they’re available to help you in your development experience, even if you’re not using TypeScript at all. And of course, if you are using TypeScript, having these will make all the difference in your experience of using an addon. So let’s do it!
How to participate
First, a couple notes to both add-on authors and add-on users, then the nitty gritty!
Addon authors
{>> TODO <<}
If you are open to someone else adding typings for your addon
One other approach you can take, if you're interested in adding types to your addon but don't have the knowledge or bandwidth to do it yourself is to add a Help Wanted issue to your repository and link it here! If your repo isn't in the top-100-addons list, I'll add it anyway in its own section. If you're
{>> TODO <<}
Add-on users
If you take a look at one of the addons on this list and the author hasn’t yet expressed any interest in adding TypeScript or TypeScript definitions to their addon, the very first thing you should do is open an issue and see if they’re open to the possibility of converting their addon to TypeScript or hosting the type definitions in the addon. We strongly recommend you just use this template when opening the issue:
Suggested Title: Interested in TypeScript?
Suggested Body:
To make it easy, you can just copy and paste this directly into the issue of a body:
Based on their answer, you can then help them convert their addon to use TypeScript, help them add type definitions to the repository, or – and this is very important – just leave them alone if they’re not interested! It’s perfectly fine if addon authors aren’t interested in using TypeScript themselves or if they don’t want to take on the extra maintenance burden of hosting type definitions. Do not badger an addon author about TypeScript! If they aren’t interested, we can fall back to using DefinitelyTyped to host type definitions!
Actually doing the work
Okay, let's dive in and talk about how to do this!
Converting an addon to TypeScript
{>> TODO <<}
Writing type definitions
As noted above, the most important thing about type definitions is that they are correct. If they're incorrect, they'll actually lead users to write wrong code, and that's a deeply frustrating experience.
Some general tips:
Wherever there is documentation, read it very carefully. It's not always correct or up to date, but it still usually gives you a good starting point. If nothing else, it is often a good guide for what the public API is.
Read the source code for the public API. This is the only way to actually be sure of what the code does. Take a look at the function arguments, and look at what is done with them. Are there optional arguments? Are the arguments "polymorphic," i.e. can you pass in either a string or an array of strings or an object as the nth argument? Does it always return the same thing or not? Etc.
Pick something you can handle! Your type definitions should capture everything about the actual behavior of an addon's classes and functions. Sometimes, this will be easy. Other times (here's looking at you, Ember CLI Mirage!) this will involve a lot of arcane type mechanics. If you're just starting out, that's okay! Pick a simpler addon. If you've got mad TypeScript chops, awesome: pick something harder!
Don't go it alone. Get input along the way. The folks on the ember-cli-typescript team and many of the people hanging out in #topic-typescript on the Ember Community Slack are happy to help review your typings work and help you go from just wrote my first type definition ever! to mentoring other people! And getting feedback along the way will help us achieve our goal
{>> TODO: how to write a good type definition <<}
Type definition basics
{>> TODO:
.d.ts
files, modules, exports <<}Writing good type definitions
For more complicated types, you may need to lean on TypeScript's optionals, generics, union and intersection types, overloading, or the combination of several of those.
Optionals
One of the most common scenarios you'll need to cover is handling optional arguments or properties
Arguments
{>> TODO <<}
Properties
There are two ways you'll commonly need to write out optional properties. One is when some items on a type are required and others are optional. In that case, you can write the type with each argument specified explicitly as being optional or not:
The other case is where every property on an object is optional. (This tends to come up when you're passing in a configuration/options hash to a function.) In that case, you can use the build-in
Partial<T>
type, which makes every property optional:If any of the arguments are required, don't use
Partial
, spell it out explicitly. Alternatively, build an intersection type from the combination of required properties and optional properties.(This is something of a last resort, but it's there when you need it!)
Union types
Union types (described here) let you describe the either-or scenario. If a function can take either a number or a string or a boolean as an argument, you can write it like this:
Likewise, if a function returns more than one kind of things, you can write it like this:
This is most useful for times when there is no distinct mapping between the input and output type. For example, the helpers in the
ember-native-dom-helpers
helpers (now living at@ember/test-helpers
) all take either astring
or anHTMLElement
as their argument, but they always return the same kind of thing. The function signature forclick
, for example, is:However, in some circumstances, a function might take more than one input type and have different output types – but each kind of input would always have the same kind of output. For that, we'll use overloading.
Overloading
With overloading, we can tell TypeScript that a single function or method has different "signatures." For example, you may recall that {>> TODO: example <<}
Generics
Structuring type definitions
The basic structure of the type definition should mirror the structure of the addon or library you're documenting. However, the layout of Ember addons imposes specific requirements that are somewhat unique. In general in TypeScript, it is a good idea to lay out more complicated definitions side-by-side with the modules they document:
However, in the current file system layout for Ember addons, the source location and the "lookup location" where you import the files from are not the same. That is, you don't
import Foo from 'an-addon/addon/services/foo';
, youimport Foo from 'an-addon/services/foo';
. This essentially constrains us to writing all of our type definitions in a single file. (The Module Unification file layout will help with this, but it will be some time before most addons are using it.)Aside: The Ember types, as they stand today, are not a good example for how to document most libraries: we have documented Ember as it exists, where you can import things both in the new modules API and via the old global. As Ember itself moves to using the module structure under the hood and those packages are actually installed on the file system, type definitions should move to mirror them.
For a simple addon you can just put the type definitions in the root at
index.d.ts
, like this:A prime example of this kind of setup is ember-test-friendly-error-handler.
{>> TODO: example addon for multiple modules in
index.d.ts
– ember-qunit maybe? <<}{>> TODO: structure – modules etc. <<}
Adding type definitions to an addon
[Reminder: only do this after you've checked with the author(s) of the addon that they're interested!]
Once you have a version of the types working solidly in your own application(s), you can open a pull request to the addon with those types. The pull request should include:
index.d.ts
file in the root of the repository"types"
key inpackage.json
pointing to the file – for the sake of forwards-compatibility, so that if the type definitions are expanded-and-moved at a later time, things don't surprisingly breakIt should also have a good writeup, describing any open questions, pain points, limitations, etc. – that will help the addon maintainer and the reviewers help you wrap everything up with a bow!
Your best bet is to solicit feedback from both the addon maintainer and from knowledgeable folks in #topic-typescript on the Ember Community Slack. The Typed Ember team, currently consisting of @dfreeman, @dwickern, @jamescdavis, and @chriskrycho, are happy to help review these requests, and over time others will be experienced enough to chip in as well!
If you get feedback that things need tweaking, don't worry! Type definitions are hard to get just right, and the definitions for Ember have been through a ton of revisions and we're constantly finding issues with and helping each other with those, too!
Publication
You should also make sure the type definition is not excluded by
.npmignore
file and if thepackage.json
is manually specifying files via the"files"
key, thatindex.d.ts
is in the list. (This is unusual for Ember addons.) See the documentation for thefiles
key for details.Adding type definitions to DefinitelyTyped
{>> TODO <<}
DefinitelyTyped is an officially supported, Microsoft-owned GitHub repository which publishes to the
@types
npm namespace. Type definitions are automatically published from each folder in thetypes
directory in the repository.The process when using DefinitelyTyped is mostly the same as when adding them directly to an addon. When opening a PR for a set of types on DefinitelyTyped, as when doing it directly to an addon, you should get reviews from other folks who are comfortable with both TypeScript and the addon. The Typed Ember team, currently consisting of @dfreeman, @dwickern, @jamescdavis, and @chriskrycho, are happy to help review these requests, and over time others will be experienced enough to chip in as well!
Once it's in place, if the addon author is up for it, you can then open a PR to add a note to their README indicating that types are available at
@types/<the-addon-name>
. You should also open a PR to this repository to update the known-typings.md file.Typings to contribute
I’ve broken this down into two categories: Top 100 Addons on Ember Observer and Other addons. Both of these are important, albeit for different reasons.
The top 100 addons on Ember Observer represent the most-installed addons in the community; their importance is probably obvious—getting typings in place for them immediately impacts the most people. Other addons or packages are those which may be downloaded less, but whose authors actively want to participate in the quest! We want to support both of these.
Top 100 Addons on Ember Observer
The top 100 add-ons in the ecosystem, by way of Ember Observer! Some of these may not need typings added; we’ll remove them as we evaluate that. There is also quite a range of variation in the complexity of these.
@types/lodash
!Ember
global; the type definition already exists there.Other addons
If your addon isn't in the top 100 on Ember Observer but you volunteer it, we'll list it here!
The text was updated successfully, but these errors were encountered: