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

feat: typescript types #18

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 45 additions & 22 deletions addon/index.js → addon/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {
task as createTaskProperty,
taskGroup as createTaskGroupProperty
taskGroup as createTaskGroupProperty,
ConcurrencyModifiable,
TaskProperty,
TaskGroupProperty
} from 'ember-concurrency';
import { computedDecoratorWithParams } from '@ember-decorators/utils/computed';
import { assert } from '@ember/debug';
Expand Down Expand Up @@ -31,7 +34,7 @@ export { default as lastValue } from './last-value';
* @returns {object|null}
* @private
*/
function extractValue(desc) {
function extractValue(desc: PropertyDescriptor) {
if ('value' in desc) {
return desc.value;
}
Expand All @@ -50,7 +53,7 @@ function extractValue(desc) {
* @returns {TaskProperty}
* @private
*/
function createTaskFromDescriptor(desc) {
function createTaskFromDescriptor(desc: PropertyDescriptor) {
assert(
'ember-concurrency-decorators: Getters and setters are not supported for tasks.',
desc.writable
Expand All @@ -74,7 +77,7 @@ function createTaskFromDescriptor(desc) {
* @returns {TaskGroupProperty}
* @private
*/
function createTaskGroupFromDescriptor(desc) {
function createTaskGroupFromDescriptor(desc: PropertyDescriptor) {
assert(
'ember-concurrency-decorators: Getters and setters are not supported for task groups.',
desc.writable
Expand All @@ -86,30 +89,45 @@ function createTaskGroupFromDescriptor(desc) {
return createTaskGroupProperty();
}

type ModifierOptions = {
[key in keyof ConcurrencyModifiable]: true | string | number
};

/**
* Applies the `options` provided using the chaining API on the given `task`.
*
* @param {object} options
* @param {TaskProperty|TaskGroupProperty} task
* @private
*/
const applyOptions = (options, task) =>
Object.entries(options).reduce((task, [key, value]) => {
if (value === true) {
return task[key]();
}
if (
typeof value === 'string' ||
typeof value === 'number' ||
Array.isArray(value)
) {
return task[key](value);
}
assert(
`ember-concurrency-decorators: Cannot apply option '${key}' of type ${typeof value} with value '${value}' to task. Either specify the option as 'true' or provide a numeric or string value.`
);
return task;
}, task);
const applyOptions = (
options: ModifierOptions,
task: TaskProperty | TaskGroupProperty
) =>
Object.entries(options).reduce(
(
task,
[key, value]: [keyof ConcurrencyModifiable, true | string | number]
) => {
if (value === true) {
// @ts-ignore
return task[key]();
}
if (
typeof value === 'string' ||
typeof value === 'number' ||
Array.isArray(value)
) {
// @ts-ignore
return task[key](value);
}
assert(
`ember-concurrency-decorators: Cannot apply option '${key}' of type ${typeof value} with value '${value}' to task. Either specify the option as 'true' or provide a numeric or string value.`
);
return task;
},
task
);

/**
* Creates a decorator function that transforms the decorated property using the
Expand All @@ -120,7 +138,12 @@ const applyOptions = (options, task) =>
* @param {object} [baseOptions={}]
* @private
*/
const createDecorator = (propertyCreator, baseOptions = {}) =>
const createDecorator = (
propertyCreator: (
desc: PropertyDescriptor
) => TaskProperty | TaskGroupProperty,
baseOptions = {}
) =>
computedDecoratorWithParams((target, key, desc, [userOptions]) =>
applyOptions(
Object.assign({}, baseOptions, userOptions),
Expand Down
33 changes: 23 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,24 @@
"lint:js": "eslint .",
"start": "ember serve",
"test": "ember test",
"test:all": "ember try:each"
"test:all": "ember try:each",
"prepublishOnly": "ember ts:precompile",
"postpublish": "ember ts:clean"
},
"dependencies": {
"@ember-decorators/utils": "^2.5.1",
"@ember-decorators/utils": "^2.5.2",
"ember-cli-babel": "^7.1.2"
},
"devDependencies": {
"@ember-decorators/babel-transforms": "^2.1.2",
"@ember/optional-features": "^0.6.3",
"@types/ember": "^2.8.32",
"@types/ember-qunit": "^3.0.3",
"@types/ember-test-helpers": "^0.7.1",
"@types/ember": "^3.0.24",
"@types/ember-qunit": "^3.4.2",
"@types/ember-test-helpers": "^1.0.3",
"@types/ember-testing-helpers": "^0.0.3",
"@types/qunit": "^2.5.2",
"@types/rsvp": "^4.0.1",
"@types/ember__test-helpers": "^0.7.5",
"@types/qunit": "^2.5.3",
"@types/rsvp": "^4.0.2",
"babel-eslint": "^8.2.6",
"broccoli-asset-rev": "^3.0.0",
"ember-cli": "~3.4.3",
Expand All @@ -42,9 +45,9 @@
"ember-cli-qunit": "^4.3.2",
"ember-cli-sri": "^2.1.1",
"ember-cli-template-lint": "^1.0.0-beta.1",
"ember-cli-typescript": "^1.3.2",
"ember-cli-typescript": "^1.4.4",
"ember-cli-uglify": "^2.1.0",
"ember-concurrency": "^0.8.19",
"ember-concurrency": "^0.8.21",
"ember-disable-prototype-extensions": "^1.1.3",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.1.0",
Expand All @@ -60,7 +63,17 @@
"eslint-plugin-prettier": "^3.0.0",
"loader.js": "^4.7.0",
"prettier": "^1.14.3",
"typescript": "^3.0.1"
"typescript": "^3.1.1"
},
"resolutions": {
"**/@types/ember": "^3.0.24",
"**/@types/ember-qunit": "^3.4.2",
"**/@types/ember-test-helpers": "^1.0.3",
"**/@types/ember-testing-helpers": "^0.0.3",
"**/@types/ember__test-helpers": "^0.7.5",
"**/@types/jquery": "^3.3.13",
"**/@types/qunit": "^2.5.3",
"**/@types/rsvp": "^4.0.2"
},
"engines": {
"node": "6.* || 8.* || >= 10.*"
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/decorators-ts-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,26 @@ module('Unit | decorators (TS)', function() {
let obj;
run(() => {
obj = Obj.create();
// @ts-ignore
obj.get('doStuff').perform();
// @ts-ignore
obj.get('a').perform();
// @ts-ignore
obj.get('b').perform();
// @ts-ignore
obj.get('c').perform();
// @ts-ignore
obj.get('d').perform();
});
// @ts-ignore
assert.equal(obj.get('doStuff.last.value'), 123);
// @ts-ignore
assert.equal(obj.get('a.last.value'), 456);
// @ts-ignore
assert.equal(obj.get('b.last.value'), 789);
// @ts-ignore
assert.equal(obj.get('c.last.value'), 12);
// @ts-ignore
assert.equal(obj.get('d.last.value'), 34);
});
});
18 changes: 13 additions & 5 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"strictPropertyInitialization": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noUnusedParameters": false,
"noImplicitReturns": true,
"experimentalDecorators": true,
"noEmitOnError": false,
Expand All @@ -34,15 +34,23 @@
"ember-concurrency-decorators/*": [
"addon/*"
],
"ember-concurrency-decorators/test-support": [
"addon-test-support"
],
"ember-concurrency-decorators/test-support/*": [
"addon-test-support/*"
],
"*": [
"types/*"
]
}
},
"include": [
"app",
"addon",
"tests",
"types"
"app/**/*",
"addon/**/*",
"tests/**/*",
"types/**/*",
"test-support/**/*",
"addon-test-support/**/*"
]
}
58 changes: 58 additions & 0 deletions types/ember-concurrency.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import ComputedProperty from "@ember/object/computed";

declare module 'ember-concurrency' {
interface ConcurrencyModifiable {
drop(): this;
enqueue(): this;
keepLatest(): this;
restartable(): this;
maxConcurrency(n: number): this;
group(groupPath: string): this;
}

interface Triggerable {
on(...eventName: string[]): this;
}

interface Cancelable {
cancelOn(...eventName: string[]): this;
}

interface Debuggable {
debug(): this;
}

interface Evented {
evented(): this;
}

interface TaskGroup {
cancelAll(): void;
}

interface Task extends TaskGroup {}

interface TaskGroupProperty
extends ConcurrencyModifiable,
Triggerable,
Cancelable,
Debuggable,
Evented {}

interface TaskProperty
extends ConcurrencyModifiable,
Triggerable,
Cancelable,
Debuggable,
Evented, ComputedProperty<() => Task> {}

export function taskGroup(): TaskGroupProperty;

export function task(
generatorFunction: (...args: any[]) => any
): TaskProperty;

export function task(encapsulatedTask: {
perform: (...args: any[]) => any;
}): TaskProperty;
}
13 changes: 13 additions & 0 deletions types/ember-decorators.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
declare module '@ember-decorators/utils/computed' {
export function computedDecoratorWithParams<
T extends object,
K extends keyof T
>(
fn: (
target: T,
key: K,
desc: PropertyDescriptor,
params: any[]
) => PropertyDescriptor
): PropertyDecorator;
}
9 changes: 9 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
initializer?(): any;
}
Loading