Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type definitions #119

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

chriskrycho
Copy link
Collaborator

This allows users of the library to get TS-powered definitions for the library without installing @types/ember-feature-flags, and enables us to provide good SemVer guarantees for this library.

Interesting/notable decisions made here:

  • We introduce a FeaturesRegistry which users can customize for improved type safety (specifically, around catching typos on their feature flag checks in e.g. isEnabled etc.). If they do not do anything with the registry, then any string key is allowed for the setup, isEnabled, enable, disable, and get functions as well as the flags property.

  • We do not provide types for making the template-side direct access to properties, e.g. {{#if this.features.someFlag}}, work. This is not possible to capture safely at this point in a way that will give the desired autocomplete in templates for Glint users while also not lying to users about what they can access directly without going through get when accessing the service in JS. (When, in the future, the library moves away from using unknownProperty() to using a native proxy, we will be able to support that.)

    For those scenarios, users will need to use get in the template, which will return unknown. That will be fine for type safety here, since there is no type narrowing.

In support of actually testing this, introduce GitHub Actions (not fully configured). Also update the README!

If it's helpful/preferred (e.g. for CHANGELOG.md purposes) I can pull out the GitHub Actions configuration into a separate PR.


The library ships with full support for TypeScript usage with the service, helper, and test helpers. The API described above works as expected, with one additional nicety and one caveat.

**Nicety:** the library provides you the ability to define statically your known feature flags by using a *registry* (as you may be familiar with from the registries for Ember's services, Ember Data models, etc.). If you define your keys (in kebab case!) in a registry like this:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woohoo! this is awesome!

@SergeAstapov
Copy link
Contributor

@chriskrycho super minor, should we update .npmignore to not include type-tests/ dir?

@chriskrycho
Copy link
Collaborator Author

That's a great call – I’ll update accordingly in a bit!

This allows users of the library to get TS-powered definitions for the
library without installing `@types/ember-feature-flags`, and enables us
to provide good SemVer guarantees for this library.

Interesting/notable decisions made here:

- We introduce a `FeaturesRegistry` which users can customize for
  improved type safety (specifically, around catching typos on their
  feature flag checks in e.g. `isEnabled` etc.). If they do not do
  anything with the registry, then any `string` key is allowed for the
  `setup`, `isEnabled`, `enable`, `disable`, and `get` functions as
  well as the `flags` property.

- We do *not* provide types for making the template-side direct access
  to properties, e.g. `{{#if this.features.someFlag}}`, work. This is
  not possible to capture safely at this point in a way that will give
  the desired autocomplete in templates for [Glint][1] users while also
  *not* lying to users about what they can access directly *without*
  going through `get` when accessing the service in JS. (When, in the
  future, the library moves away from using `unknownProperty()` to
  using a native proxy, we *will* be able to support that.)

  For those scenarios, users will need to use `get` in the template,
  which will return `unknown`. That will be fine for type safety here,
  since there is no type narrowing.

[1]: https://github.com/typed-ember/glint
- This tests against the same minimum version as the existing type
  definitions on DefinitelyTyped, so users can upgrade to at least the
  version supported there, and then switch over to using this. Note
  that type tests do *not* use Ember Try, and therefore do not drift
  the lockfile. This is intentional: the emitted types here are wholly
  unaffected by the rest of the dependencies other than those in
  `@types`, and for compatibility with TS we only care about the types.
  This makes that part of CI run *much* faster.

- The type tests allow failures against the `typescript@next` version,
  just as the runtime tests do for Ember Canary releases.
}
```

This applies to all the values. If you do *not* add any keys to the `FeatureFlags` interface, the types will fall back to simply allowing any string and returning a boolean value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seem it should be FeaturesRegistry instead of FeatureFlags?

@@ -0,0 +1,11 @@
import Helper from "@ember/component/helper";
import { Keys } from "ember-feature-flags/services/features";
Copy link
Contributor

@SergeAstapov SergeAstapov May 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, should this be import type?

@@ -0,0 +1,11 @@
import Helper from "@ember/component/helper";
import { Keys } from "ember-feature-flags/services/features";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our of curiosity, should this be import type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could, but since it's in a .d.ts file they're all import type effectively.

@RobbieTheWagner
Copy link

@chriskrycho how are things looking on this? Anything I can help with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants