Skip to content

Commit

Permalink
kerosene: Add overload utility types
Browse files Browse the repository at this point in the history
  • Loading branch information
nhardy committed Feb 28, 2021
1 parent a95d24c commit a538831
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 28 deletions.
3 changes: 2 additions & 1 deletion packages/kerosene-test/package.json
@@ -1,6 +1,6 @@
{
"name": "@kablamo/kerosene-test",
"version": "0.0.9",
"version": "0.0.10",
"repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene-test",
"bugs": {
"url": "https://github.com/KablamoOSS/kerosene/issues"
Expand Down Expand Up @@ -46,6 +46,7 @@
"utils"
],
"dependencies": {
"@kablamo/kerosene": "^0.0.20",
"@types/lodash": "^4.14.168",
"@types/sinon": "^9.0.10",
"lodash": "^4.17.20",
Expand Down
8 changes: 4 additions & 4 deletions packages/kerosene-test/readme.md
Expand Up @@ -34,21 +34,21 @@ Stubs `properties` on the `target` object, and returns a function which restores

#### `JestMock<T>`

Shorthand for `jest.Mock<ReturnType<T>, Parameters<T>>;`.
Shorthand for `jest.Mock<OverloadedReturnType<T>, OverloadedParameters<T>> & T;`.

#### `JestSpied<T>`

Shorthand for `jest.SpyInstance<ReturnType<T>, Parameters<T>>;`.
Shorthand for `jest.SpyInstance<OverloadedReturnType<T>, OverloadedParameters<T>> & T;`.

### Sinon

#### `SinonSpied<T>`

Shorthand for `sinon.SinonSpy<Parameters<T>, ReturnType<T>>;`.
Shorthand for `sinon.SinonSpy<OverloadedParameters<T>, OverloadedReturnType<T>> & T;`.

#### `SinonStubbed<T>`

Shorthand for `sinon.SinonStub<Parameters<T>, ReturnType<T>>;`.
Shorthand for `sinon.SinonStub<OverloadedParameters<T>, OverloadedReturnType<T>> & T;`.

---

Expand Down
24 changes: 14 additions & 10 deletions packages/kerosene-test/src/jest/index.ts
@@ -1,15 +1,19 @@
import { OverloadedParameters, OverloadedReturnType } from "@kablamo/kerosene";

/**
* Shorthand for `jest.Mock<ReturnType<T>, Parameters<T>>;`
* Shorthand for `jest.Mock<OverloadedReturnType<T>, OverloadedParameters<T>> & T;`
*/
export type JestMock<T extends (...args: any[]) => any> = jest.Mock<
ReturnType<T>,
Parameters<T>
>;
export type JestMock<T> = jest.Mock<
OverloadedReturnType<T>,
OverloadedParameters<T>
> &
T;

/**
* Shorthand for `jest.SpyInstance<ReturnType<T>, Parameters<T>>;`
* Shorthand for `jest.SpyInstance<OverloadedReturnType<T>, OverloadedParameters<T>> & T;`
*/
export type JestSpied<T extends (...args: any[]) => any> = jest.SpyInstance<
ReturnType<T>,
Parameters<T>
>;
export type JestSpied<T> = jest.SpyInstance<
OverloadedReturnType<T>,
OverloadedParameters<T>
> &
T;
23 changes: 13 additions & 10 deletions packages/kerosene-test/src/sinon/index.ts
@@ -1,17 +1,20 @@
import { OverloadedParameters, OverloadedReturnType } from "@kablamo/kerosene";
import sinon from "sinon";

/**
* Shorthand for `sinon.SinonSpy<Parameters<T>, ReturnType<T>>;`
* Shorthand for `sinon.SinonSpy<OverloadedParameters<T>, OverloadedReturnType<T>> & T;`
*/
export type SinonSpied<T extends (...args: any[]) => any> = sinon.SinonSpy<
Parameters<T>,
ReturnType<T>
>;
export type SinonSpied<T> = sinon.SinonSpy<
OverloadedParameters<T>,
OverloadedReturnType<T>
> &
T;

/**
* Shorthand for `sinon.SinonStub<Parameters<T>, ReturnType<T>>;`
* Shorthand for `sinon.SinonStub<OverloadedParameters<T>, OverloadedReturnType<T>> & T;`
*/
export type SinonStubbed<T extends (...args: any[]) => any> = sinon.SinonStub<
Parameters<T>,
ReturnType<T>
>;
export type SinonStubbed<T> = sinon.SinonStub<
OverloadedParameters<T>,
OverloadedReturnType<T>
> &
T;
4 changes: 2 additions & 2 deletions packages/kerosene-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@kablamo/kerosene-ui",
"version": "0.0.20",
"version": "0.0.21",
"repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene-ui",
"bugs": {
"url": "https://github.com/KablamoOSS/kerosene/issues"
Expand All @@ -22,7 +22,7 @@
},
"dependencies": {
"@babel/runtime": "^7.12.13",
"@kablamo/kerosene": "^0.0.19",
"@kablamo/kerosene": "^0.0.20",
"@types/lodash": "^4.14.168",
"lodash": "^4.17.20"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/kerosene/package.json
@@ -1,6 +1,6 @@
{
"name": "@kablamo/kerosene",
"version": "0.0.19",
"version": "0.0.20",
"repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene",
"bugs": {
"url": "https://github.com/KablamoOSS/kerosene/issues"
Expand Down
16 changes: 16 additions & 0 deletions packages/kerosene/readme.md
Expand Up @@ -240,6 +240,22 @@ From a union type `T`, allows properties which are not shared by all members to

Removes the `readonly` modifier from all properties in `T`.

### `Overloads<T>`

From an overloaded function `T`, infer each overload as a tuple element.

### `OverloadedParameters<T>`

For an overloaded function `T`, infer the union of parameters for all overloads.

### `OverloadedReturnType<T>`

For an overloaded function `T`, infer the union of return types for all overloads.

### `OverloadedReturnTypeWhen<T, P>`

For an overloaded function `T`, infer the return type for the specific overload when parameters match `P`.

### `PickBy<T, TValue>`

Creates a new type from `T` including only keys where the value is assignable to type `TValue`.
Expand Down
79 changes: 79 additions & 0 deletions packages/kerosene/src/types/index.ts
Expand Up @@ -79,6 +79,85 @@ export type MergedUnion<T extends object> = __MergedUnion__<T, T>;
*/
export type Mutable<T> = { -readonly [P in keyof T]: T[P] };

/**
* From an overloaded function `T`, infer each overload as a tuple element
*/
export type Overloads<T> = T extends {
(...args: infer P1): infer R1;
(...args: infer P2): infer R2;
(...args: infer P3): infer R3;
(...args: infer P4): infer R4;
(...args: infer P5): infer R5;
(...args: infer P6): infer R6;
}
? [
(...args: P1) => R1,
(...args: P2) => R2,
(...args: P3) => R3,
(...args: P4) => R4,
(...args: P5) => R5,
(...args: P6) => R6,
]
: T extends {
(...args: infer P1): infer R1;
(...args: infer P2): infer R2;
(...args: infer P3): infer R3;
(...args: infer P4): infer R4;
(...args: infer P5): infer R5;
}
? [
(...args: P1) => R1,
(...args: P2) => R2,
(...args: P3) => R3,
(...args: P4) => R4,
(...args: P5) => R5,
]
: T extends {
(...args: infer P1): infer R1;
(...args: infer P2): infer R2;
(...args: infer P3): infer R3;
(...args: infer P4): infer R4;
}
? [
(...args: P1) => R1,
(...args: P2) => R2,
(...args: P3) => R3,
(...args: P4) => R4,
]
: T extends {
(...args: infer P1): infer R1;
(...args: infer P2): infer R2;
(...args: infer P3): infer R3;
}
? [(...args: P1) => R1, (...args: P2) => R2, (...args: P3) => R3]
: T extends {
(...args: infer P1): infer R1;
(...args: infer P2): infer R2;
}
? [(...args: P1) => R1, (...args: P2) => R2]
: T extends (...args: infer P1) => infer R1
? [(...args: P1) => R1]
: never;

/**
* For an overloaded function `T`, infer the union of parameters for all overloads
*/
export type OverloadedParameters<T> = Parameters<Overloads<T>[number]>;

/**
* For an overloaded function `T`, infer the union of return types for all overloads
*/
export type OverloadedReturnType<T> = ReturnType<Overloads<T>[number]>;

/**
* For an overloaded function `T`, infer the return type for the specific overload when parameters match `P`
*/
export type OverloadedReturnTypeWhen<T, P extends unknown[]> = T extends (
...args: P
) => infer R
? R
: never;

/**
* Creates a new type from `T` including only keys where the value is assignable to type `TValue`
*/
Expand Down

0 comments on commit a538831

Please sign in to comment.