-
-
Notifications
You must be signed in to change notification settings - Fork 25
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
Allow task
to work as a "pass-through" wrapper for TS support
#76
Conversation
FWIW, I very much prefer this approach! It avoids introducing any other new API surface, and looks like it should be easy to iterate toward a “resources”-based approach (the |
I'm also a big fan of this, particularly if Those two things together would deliver end-to-end type safety without putting the burden on the caller to remember to use |
tests/unit/decorators-test.ts
Outdated
if (/^2\./.test(Ember.VERSION)) { | ||
// Have access computed properties with .get w/ Ember 2.x | ||
// @ts-ignore | ||
assert.equal(subject.get('doStuff.last.value'), 123); | ||
// @ts-ignore | ||
assert.equal(subject.get('a.last.value'), 456); | ||
// @ts-ignore | ||
assert.equal(subject.get('b.last.value'), 789); | ||
// @ts-ignore | ||
assert.equal(subject.get('c.last.value'), 12); | ||
// @ts-ignore | ||
assert.equal(subject.get('d.last.value'), 34); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When machty/ember-concurrency#363 lands, we can remove this ugly special-casing for the 2.18 try case and just use, e.g.
assert.equal(subject.get('doStuff').get('last')?.value, 123);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't resist: b5dbcb4
chancancode/ember-concurrency-async#6 makes this work with async tasks e.g. class MyClass {
one = 1;
@task
myTask = task(async function(this: MyClass) {
await this.one;
return 2;
});
@task
myTask = task(async () => {
await this.one;
return 2;
});
} |
dbf2d1a
to
ee8b9f6
Compare
AsyncTask types and tests for async tasks w/ task wrapper are here: jamescdavis#1 but we obviously can't drop them in like that. Need to think about how to make them manually importable like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overloading task
in this way and using class field syntax is a bit confusing to me, as I'm not sure there's really a need for the decorator in that context?
If you just use class field syntax without using the decorator and using task
provided by ember-concurrency
1.2.0 itself, does it not properly type?
It would type correctly but behave in an undesirable ay: assignment to a class field is a per-instance setup, unlike methods which end up on the prototype. Decorators can transform properties or methods, and can in fact transform the property into a prototype-bound method. Using the two in combination is definitely odd, but it’s what’s necessary for now. It’s also close to what we’ll likely end up with in a resources-driven design in the future, where a task usage might look something like this: import Component from '@glimmer/component';
import { use } from '@ember/something-something-resources';
import { task } from 'ember-concurrency';
export default class MyComponent extends Component {
@use myTask = task(function*() {
// ... the normal task body ...
});
} |
What @chriskrycho said and it throws an error: https://ember-twiddle.com/55d9db44e9958d7fab70fe1fa91e218b?openFiles=components.undecorated-task%5C.js%2C |
The double usage of |
Some more thoughts about this design that I had a when I proposed it @buschtoens:
|
I don't think it's the overloading of I do find the |
So, you're thinking of making |
|
|
I think my preferences would lie with something like |
Now that you mention it, I believe @task
myTask = (function*(something: string) {
yield something;
return 42;
} as unknown) as ComputedProperty<Task<number, [string]> & EmberObject>; except that it automatically infers the return vale and arguments and isn't ugly as hell. What do we think about?: @task
myTask = asTask(function*(something: string) {
yield something;
return 42;
}); React with: 👍 , 👎, or 😕 |
As far as I can tell, if we are not overloading, then that is pretty much the same signature as |
@chancancode well, actually, yeah! import { taskFor } from 'ember-concurrency-ts';
export default class MyComponent extends Component {
@task
myTask = taskFor(function*(something: string) {
yield something;
return 42;
});
} as well as import { taskFor } from 'ember-concurrency-ts';
export default class MyComponent extends Component {
theAnswer = 42;
@task
myTask = taskFor(async (something: string) => {
await something;
return this.theAnswer;
});
} when coupled with a slightly adjusted chancancode/ember-concurrency-async#6. So maybe there's actually nothing new here. ¯\_(ツ)_/¯ I would like to see this usage illustrated as an option on http://ember-concurrency.com/docs/typescript (and in |
Well, works fine for types. We'd have to adjust this assertion for Here's a PR that does that: chancancode/ember-concurrency-ts#1 |
Here's a PR that makes using |
Closing in favor of chancancode/ember-concurrency-ts#1 |
This is based on #56 now that types have landed in
ember-concurrency
.The idea is that
task
can act as both a decorator and as a function that wraps a task generator or encapsulated task descriptor. When used as a wrapper, it simply passes through the argument while providing a return type ofTask
. This allows you to interact with the task property exactly as you would in JavaScript, but with the type-safety of TypeScript:Note: This is an alternative approach to https://github.com/chancancode/ember-concurrency-ts
@chancancode @dfreeman @chriskrycho @buschtoens