-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support
Signature
types for modifiers
Details ------- Following the design pioneered in emberjs/rfcs#748, introduce a new `Signature` type and use it in defining the types for both function- and class-based modifiers. This allows end users to write, for example: interface PlaySig { Args: { Named: { when: boolean; } } Element: HTMLMediaElement; } export default modifier<PlaySig>((el, _, { when: shouldPlay }) => { if (shouldPlay) { el.play(); } else { el.pause(); } }); This supports both `Named` and `Positional` args, and works equally well with class-based modifiers. It also provides the `Element` type as `Element` by default, and provides internal type utilities as well as one external-facing type utility to make writing the type of `args` when passed to a modifier `constructor` easy to do in terms of the `Signature` which represents the modifier. Users do not *need* to type this form: the form using basic inference continues to work as well: export default modifier(( el: HTMLMediaElement, _: [], { when: shouldPlay }: { when: boolean } ) => { if (shouldPlay) { el.play(); } else { el.pause(); } })); That is: the support for `Signatures` is strictly *new* capability which was not present before. The same kind of signature works with class-based modifiers as well, while retaining backward compatibility with the `Args`-based signature and declaration on the subclass `element` field directly. To support that in a way that does not require users to name their args over and over again, introduce an `ArgsFor` type utility which translates from the signature type to the runtime form: import Modifier, { ArgsFor } from 'ember-modifier'; interface PlaySig { Args: { Named: { when: boolean; }; }; Element: HTMLMediaElement; } class MyModifier extends Modifier<PlaySig> { constructor(owner: unknown, args: ArgsFor<PlaySig>) { super(owner, args); // ... } didReceiveArguments() { const shouldPlay = this.args.named.when; if (shouldPlay) { this.element.play(); } else { this.element.pause(); } } } Additionally, the `modifier` function now returns an opaque `FunctionBasedModifier` type. This mostly exists to provide nice hooks for tooling to hook onto, but it has the added benefit of showing something besides `unknown` in an editor, and that "something" shows the arguments and element specified for the modifier. Supporting changes ------------------ - Update the README to match, and fix a *lot* of long-since outdated documentation along the way. - Loosen type test constraint to support older TS versions The new type signature *is* compatible (as the tests on TS 4.5+ show), but on older versions of TS, it does not check under a type equality check, only under a type matching check. For the purposes of the specific test in question, that's perfectly fine, because the *other* type tests cover inference and resolution correctly.
- Loading branch information
1 parent
f1e7169
commit 7fb8d2a
Showing
13 changed files
with
562 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.