diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffdb651..8eb8cbc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ Change Log
- changed format of `.factory` `.service` and `.resolve`
- you can now pass an `opts` parameter when registering a factory i.e. `.factory(fn, { lifecycle: 'none' })`
- you can now pass an `opts` parameter when resolving i.e. `.resolve({ optional: true })`
+- `resolveWith` now has a nicer syntax for ts inference: `.resolveWith([ 'val1', 'val2' ])`. The original syntax i.e. `.resolveWith({ dep1: 'val1' })` is still valid.
#### Breaking Changes
- if you attempt to resolve a global like `Window` without registering it first, rather than throw an error, you will now get the global variable
diff --git a/package.json b/package.json
index eb52ea2..945e24b 100644
--- a/package.json
+++ b/package.json
@@ -6,9 +6,9 @@
"module": "dist/es/jpex.js",
"types": "dist/es/index.d.ts",
"scripts": {
- "test": "ava",
- "test:debug": "ava debug",
- "coverage": "nyc ava",
+ "test": "BABEL_DISABLE_CACHE=1 ava",
+ "test:debug": "BABEL_DISABLE_CACHE=1 ava debug",
+ "coverage": "BABEL_DISABLE_CACHE=1 nyc ava",
"lint": "eslint './src/**/*.ts' && eslint './plugin/**/*.ts' && tsc --noEmit",
"build:prepare": "rm -rf dist",
"build:js": "rollup --config ./rollup.config.js",
diff --git a/plugin/resolveWith.ts b/plugin/resolveWith.ts
index 2479074..de74f3e 100644
--- a/plugin/resolveWith.ts
+++ b/plugin/resolveWith.ts
@@ -27,7 +27,33 @@ const resolveWith = (
args.unshift(t.stringLiteral(name));
} else if (t.isTSTypeLiteral(type) || t.isTSFunctionType(type)) {
throw new Error('Currently resolving with a literal type is not supported');
+ } else {
+ return;
+ }
+
+ if (!t.isArrayExpression(args[1])) {
+ return;
}
+
+ const namedDependencies: t.ObjectProperty[] = [];
+ let i = 1;
+ let namedType = getTypeParameter(path, i);
+ while (namedType) {
+ const name = getConcreteTypeName(namedType, filename, publicPath, programPath);
+ if (name != null) {
+ const value = args[1].elements[i - 1];
+ const key = t.stringLiteral(name);
+ // @ts-ignore
+ const prop = t.objectProperty(key, value);
+ namedDependencies.push(prop);
+ } else if (t.isTSTypeLiteral(type) || t.isTSFunctionType(type)) {
+ throw new Error('Currently resolving with a literal type is not supported');
+ }
+ // eslint-disable-next-line no-plusplus
+ namedType = getTypeParameter(path, ++i);
+ }
+
+ args.splice(1, 1, t.objectExpression(namedDependencies));
};
export default resolveWith;
diff --git a/src/__tests__/resolve.test.ts b/src/__tests__/resolve.test.ts
index dab6fcf..2cabf63 100644
--- a/src/__tests__/resolve.test.ts
+++ b/src/__tests__/resolve.test.ts
@@ -54,8 +54,10 @@ test('resolves named dependencies', (t) => {
type Named = string;
jpex.factory((named: Named) => named);
- const result = jpex.resolveWith({
- [jpex.infer()]: 'pop',
+ const result = jpex.resolve({
+ with: {
+ [jpex.infer()]: 'pop',
+ },
});
t.is(result, 'pop');
diff --git a/src/__tests__/resolveWith.test.ts b/src/__tests__/resolveWith.test.ts
new file mode 100644
index 0000000..41e7c3e
--- /dev/null
+++ b/src/__tests__/resolveWith.test.ts
@@ -0,0 +1,78 @@
+import anyTest, { TestInterface } from 'ava';
+import base, { JpexInstance } from '..';
+
+const test: TestInterface<{
+ jpex: JpexInstance,
+}> = anyTest;
+
+test.beforeEach((t) => {
+ const jpex = base.extend();
+
+ t.context = {
+ jpex,
+ };
+});
+
+test('it resolves with given values (js)', (t) => {
+ const { jpex } = t.context;
+
+ jpex.factory('A', [ 'B', 'C', 'D' ], (b, c, d) => {
+ return b + c + d;
+ });
+
+ const result = jpex.resolveWith('A', {
+ B: 'b',
+ C: 'c',
+ D: 'd',
+ });
+
+ t.is(result, 'bcd');
+});
+
+test('it resolves with given values (ts)', (t) => {
+ const { jpex } = t.context;
+
+ type A = string;
+ type B = string;
+ type C = string;
+ type D = string;
+
+ jpex.factory((b: B, c: C, d: D) => b + c + d);
+
+ const result = jpex.resolveWith({
+ [jpex.infer()]: 'b',
+ [jpex.infer()]: 'c',
+ [jpex.infer()]: 'd',
+ });
+
+ t.is(result, 'bcd');
+});
+
+test('it resolves using type inference (1)', (t) => {
+ const { jpex } = t.context;
+ type A = string;
+ type B = string;
+
+ jpex.factory((b: B) => `a${b}`);
+
+ const result = jpex.resolveWith([ 'b' ]);
+
+ t.is(result, 'ab');
+});
+
+test('it resolves with type inference (6)', (t) => {
+ const { jpex } = t.context;
+ type A = string;
+ type B = string;
+ type C = string;
+ type D = string;
+ type E = string;
+ type F = string;
+ type G = string;
+
+ jpex.factory((b: B, c: C, d: D, e: E, f: F, g: G) => `a${b}${c}${d}${e}${f}${g}`);
+
+ const result = jpex.resolveWith([ 'b', 'c', 'd', 'e', 'f', 'g' ]);
+
+ t.is(result, 'abcdefg');
+});
diff --git a/src/types/JpexInstance.ts b/src/types/JpexInstance.ts
index d6dcf69..46c9e62 100644
--- a/src/types/JpexInstance.ts
+++ b/src/types/JpexInstance.ts
@@ -36,8 +36,14 @@ export interface JpexInstance {
resolve(name: Dependency, opts?: ResolveOpts): any,
resolve(opts?: ResolveOpts): T,
- resolveWith(name: Dependency, namedParameters: NamedParameters): any
- resolveWith(namedParameters: NamedParameters): T,
+ resolveWith(name: Dependency, namedParameters: NamedParameters, opts?: ResolveOpts): any
+ resolveWith(namedParameters: NamedParameters, opts?: ResolveOpts): T,
+ resolveWith(args: [ A ], opts?: ResolveOpts): T,
+ resolveWith(args: [ A, B ], opts?: ResolveOpts): T,
+ resolveWith(args: [ A, B, C ], opts?: ResolveOpts): T,
+ resolveWith(args: [ A, B, C, D ], opts?: ResolveOpts): T,
+ resolveWith(args: [ A, B, C, D, E ], opts?: ResolveOpts): T,
+ resolveWith(args: [ A, B, C, D, E, F ], opts?: ResolveOpts): T,
encase>(
dependencies: Dependency[],