inferred-types 0.33.0 → 0.33.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -0
- package/dist/index.d.ts +1182 -1125
- package/dist/index.js +73 -182
- package/dist/index.mjs +70 -175
- package/package.json +16 -15
- package/src/{utility/errors → errors}/ReadOnlyViolation.ts +0 -0
- package/src/{utility/errors → errors}/index.ts +0 -0
- package/src/index.ts +1 -3
- package/src/{utility → runtime}/README.md +0 -0
- package/src/{utility → runtime}/api/api.ts +0 -0
- package/src/{utility → runtime}/api/index.ts +0 -0
- package/src/{utility/modelling → runtime/builders}/Model.ts +0 -0
- package/src/runtime/builders/url.ts +15 -0
- package/src/{utility/boolean-logic → runtime/combinators}/and.ts +0 -0
- package/src/{utility/boolean-logic → runtime/combinators}/filter.ts +0 -0
- package/src/{utility/boolean-logic → runtime/combinators}/index.ts +0 -0
- package/src/{utility/boolean-logic → runtime/combinators}/not.ts +0 -0
- package/src/{utility/boolean-logic → runtime/combinators}/or.ts +0 -0
- package/src/{utility → runtime}/createFnWithProps.ts +0 -0
- package/src/{utility → runtime}/dictionary/arrayToKeyLookup.ts +0 -0
- package/src/{utility → runtime}/dictionary/defineProperties.ts +0 -0
- package/src/{utility → runtime}/dictionary/dictArr.ts +0 -0
- package/src/{utility → runtime}/dictionary/dictionaryTransform.ts +0 -0
- package/src/{utility → runtime}/dictionary/entries.ts +0 -0
- package/src/{utility → runtime}/dictionary/index.ts +0 -0
- package/src/{utility → runtime}/dictionary/kv/dictToKv.ts +1 -1
- package/src/{utility → runtime}/dictionary/kv/filterDictArray.ts +1 -1
- package/src/{utility → runtime}/dictionary/kv/index.ts +0 -0
- package/src/{utility → runtime}/dictionary/kv/kv.ts +0 -0
- package/src/{utility → runtime}/dictionary/kv/kvToDict.ts +0 -0
- package/src/{utility → runtime}/dictionary/mapTo.ts +0 -0
- package/src/{utility → runtime}/dictionary/mapValues.ts +0 -0
- package/src/{utility → runtime}/dictionary/merge.ts +0 -0
- package/src/{utility → runtime}/dictionary/strArrayToDict.ts +0 -0
- package/src/{utility → runtime}/index.ts +1 -3
- package/src/{utility → runtime}/keys.ts +0 -0
- package/src/{utility → runtime}/lists/asArray.ts +0 -0
- package/src/{utility → runtime}/lists/groupBy.ts +0 -0
- package/src/{utility → runtime}/lists/index.ts +0 -0
- package/src/{utility → runtime}/literals/ExplicitFunction.ts +0 -0
- package/src/runtime/literals/Suggest.ts +19 -0
- package/src/{utility → runtime}/literals/arrayToObject.ts +0 -0
- package/src/runtime/literals/box.ts +77 -0
- package/src/{utility → runtime}/literals/defineType.ts +0 -0
- package/src/{utility → runtime}/literals/identity.ts +0 -0
- package/src/{utility → runtime}/literals/index.ts +2 -0
- package/src/{utility → runtime}/literals/literal.ts +0 -0
- package/src/{utility → runtime}/ruleset.ts +0 -0
- package/src/{utility → runtime}/runtime/README.md +0 -0
- package/src/{utility → runtime}/runtime/condition.ts +0 -0
- package/src/{utility → runtime}/runtime/index.ts +1 -2
- package/src/{utility → runtime}/runtime/type.ts +1 -1
- package/src/{utility → runtime}/runtime/withValue.ts +0 -0
- package/src/{utility → runtime}/state/Configurator.ts +0 -0
- package/src/{utility → runtime}/state/FluentConfigurator.ts +0 -0
- package/src/{utility → runtime}/state/index.ts +0 -0
- package/src/{utility/runtime → runtime/type-checks}/ifTypeOf.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/index.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isArray.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isBoolean.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isFalse.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isFunction.ts +11 -2
- package/src/{utility/runtime/conditions → runtime/type-checks}/isNull.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isNumber.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isObject.ts +1 -1
- package/src/{utility/runtime/conditions → runtime/type-checks}/isString.ts +13 -5
- package/src/{utility/runtime/conditions → runtime/type-checks}/isSymbol.ts +0 -0
- package/src/{utility/runtime/conditions → runtime/type-checks}/isTrue.ts +1 -1
- package/src/{utility/runtime/conditions → runtime/type-checks}/isUndefined.ts +1 -1
- package/src/runtime/type-checks/startsWith.ts +109 -0
- package/src/{shared → runtime}/valueTypes.ts +0 -0
- package/src/types/FunctionType.ts +12 -2
- package/src/types/Mutable.ts +1 -1
- package/src/types/alphabetic/Url.ts +29 -0
- package/src/types/alphabetic/alpha-characters.ts +8 -0
- package/src/types/alphabetic/index.ts +1 -0
- package/src/types/dictionary/MapTo.ts +2 -2
- package/src/types/index.ts +2 -2
- package/src/types/lists/AfterFirst.ts +10 -0
- package/src/types/lists/First.ts +8 -0
- package/src/types/lists/FirstString.ts +4 -0
- package/src/types/lists/Split.ts +21 -0
- package/src/types/lists/index.ts +4 -0
- package/src/types/ruleset-types.ts +1 -1
- package/src/types/type-checks/EndsWith.ts +22 -0
- package/src/types/{TypeInfo → type-checks}/Extends.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/Includes.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/IsBooleanLiteral.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/IsLiteral.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/IsNumericLiteral.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/IsScalar.ts +0 -0
- package/src/types/{TypeInfo → type-checks}/IsStringLiteral.ts +2 -4
- package/src/types/{TypeInfo → type-checks}/IsUndefined.ts +0 -0
- package/src/types/type-checks/StartsWith.ts +43 -0
- package/src/types/{TypeInfo → type-checks}/TypeDefault.ts +1 -1
- package/src/types/{TypeInfo → type-checks}/index.ts +3 -1
- package/src/types/{TypeInfo/IsObject.ts → type-checks/object.ts} +0 -0
- package/src/types/type-checks/string.ts +21 -0
- package/src/types/type-conversion/TupleToUnion.ts +1 -3
- package/tests/ExplicitFunction-spec.ts +1 -1
- package/tests/arrayToKeyLookup-spec.ts +1 -1
- package/tests/arrayToObject-spec.ts +1 -1
- package/tests/boolean-logic/boolean.spec.ts +1 -1
- package/tests/boolean-logic/filter.spec.ts +1 -1
- package/tests/defineType-spec.ts +1 -1
- package/tests/dictionary/Get.spec.ts +1 -1
- package/tests/dictionary/TypeDefault.test.ts +2 -2
- package/tests/dictionary/mapTo.test.ts +1 -1
- package/tests/dictionary/merge.test.ts +1 -1
- package/tests/dictionaryTransform-spec.ts +1 -1
- package/tests/ifTypeOf-spec.ts +3 -2
- package/tests/kv/dict-to-kv-and-back.spec.ts +2 -2
- package/tests/kv/entries-spec.ts +1 -1
- package/tests/kv/keys.spec.ts +1 -1
- package/tests/kv/kv-spec.ts +1 -1
- package/tests/lists/First.test.ts +43 -0
- package/tests/lists/Split.test.ts +29 -0
- package/tests/lists/asArray.test.ts +1 -1
- package/tests/lists/dictArr.test.ts +1 -1
- package/tests/literal-spec.ts +1 -1
- package/tests/{string-literals → literals}/AllCaps.spec.ts +0 -0
- package/tests/{string-literals → literals}/CamelCase.spec.ts +0 -0
- package/tests/{string-literals → literals}/Dasherize.spec.ts +0 -0
- package/tests/{string-literals → literals}/HasUppercase.spec.ts +0 -0
- package/tests/{string-literals → literals}/PascalCase.spec.ts +0 -0
- package/tests/{string-literals → literals}/SnakeCase.spec.ts +0 -0
- package/tests/literals/box.test.ts +77 -0
- package/tests/{string-literals → literals}/whitespace-capture.spec.ts +0 -0
- package/tests/mapValues-spec.ts +1 -1
- package/tests/runtime/condition.spec.ts +1 -1
- package/tests/runtime/if-is.spec.ts +158 -2
- package/tests/runtime/type.spec.ts +1 -1
- package/tests/strArrayToDict-spec.ts +1 -1
- package/tests/withValue.spec.ts +1 -1
- package/vitest.config.ts +2 -5
- package/src/Mutation/MutationFunction.ts +0 -26
- package/src/Mutation/MutationIdentity.ts +0 -36
- package/src/Mutation/index.ts +0 -14
- package/src/shared/README.md +0 -3
- package/src/shared/index.ts +0 -15
- package/src/shared/randomString.ts +0 -5
- package/src/shared/uuid.ts +0 -5
- package/src/types/First.ts +0 -4
- package/src/utility/modelling/index.ts +0 -12
- package/tests/MutationIdentity-spec.ts +0 -25
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import { describe, it } from "vitest";
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ifBoolean,
|
|
6
|
+
ifNumber,
|
|
7
|
+
ifString,
|
|
8
|
+
ifTrue,
|
|
9
|
+
ifUndefined,
|
|
10
|
+
isTrue,
|
|
11
|
+
} from "src/runtime/type-checks";
|
|
12
|
+
import { EndsWith, StartsWith } from "src/types";
|
|
13
|
+
import { ifStartsWith, startsWith } from "src/runtime/type-checks/startsWith";
|
|
14
|
+
import { box } from "src/runtime/literals";
|
|
5
15
|
|
|
6
16
|
describe("runtime if/is", () => {
|
|
7
17
|
it("ifString(v,i,e)", () => {
|
|
@@ -50,6 +60,61 @@ describe("runtime if/is", () => {
|
|
|
50
60
|
const cases: cases = [true, true, true];
|
|
51
61
|
});
|
|
52
62
|
|
|
63
|
+
it("ifTrue(v,i,e) with boxed functions", () => {
|
|
64
|
+
const f1 = box(<T extends string>(input: T) => `Hello ${input}` as const);
|
|
65
|
+
const f2 = box(<T extends string>(input: T) => `Get out ${input}!` as const);
|
|
66
|
+
const t = <T extends string, B extends boolean>(i: T, nice: B) => {
|
|
67
|
+
return isTrue(nice) ? f1.unbox()(i) : f2.unbox()(i);
|
|
68
|
+
};
|
|
69
|
+
const t2 = <T extends string, B extends boolean>(i: T, nice: B) =>
|
|
70
|
+
ifTrue(nice, f1.unbox()(i), f2.unbox()(i));
|
|
71
|
+
|
|
72
|
+
// both approaches produce correct result
|
|
73
|
+
const r1 = t("Joe", true);
|
|
74
|
+
const r2 = t2("Joe", true);
|
|
75
|
+
expect(r1).toBe("Hello Joe");
|
|
76
|
+
expect(r2).toBe("Hello Joe");
|
|
77
|
+
|
|
78
|
+
// only the "ifTrue" approach resolves fully at design time
|
|
79
|
+
type R1 = typeof r1;
|
|
80
|
+
type R2 = typeof r2;
|
|
81
|
+
|
|
82
|
+
type cases = [
|
|
83
|
+
// still get union type with `isTrue` conditional
|
|
84
|
+
Expect<Equal<R1, "Hello Joe" | "Get out Joe!">>,
|
|
85
|
+
// but encapsulating both outcomes in `ifTrue` resolves the union
|
|
86
|
+
Expect<Equal<R2, "Hello Joe">>
|
|
87
|
+
];
|
|
88
|
+
const cases: cases = [true, true];
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("ifTrue(v,i,e) with string literal functions", () => {
|
|
92
|
+
const f1 = <T extends string>(input: T) => `Hello ${input}` as const;
|
|
93
|
+
const f2 = <T extends string>(input: T) => `Get out ${input}!` as const;
|
|
94
|
+
const t = <T extends string, B extends boolean>(i: T, nice: B) => {
|
|
95
|
+
return isTrue(nice) ? f1(i) : f2(i);
|
|
96
|
+
};
|
|
97
|
+
const t2 = <T extends string, B extends boolean>(i: T, nice: B) => ifTrue(nice, f1(i), f2(i));
|
|
98
|
+
|
|
99
|
+
// both approaches produce correct result
|
|
100
|
+
const r1 = t("Joe", true);
|
|
101
|
+
const r2 = t2("Joe", true);
|
|
102
|
+
expect(r1).toBe("Hello Joe");
|
|
103
|
+
expect(r2).toBe("Hello Joe");
|
|
104
|
+
|
|
105
|
+
// only the "ifTrue" approach resolves fully at design time
|
|
106
|
+
type R1 = typeof r1;
|
|
107
|
+
type R2 = typeof r2;
|
|
108
|
+
|
|
109
|
+
type cases = [
|
|
110
|
+
// still get union type with `isTrue` conditional
|
|
111
|
+
Expect<Equal<R1, "Hello Joe" | "Get out Joe!">>,
|
|
112
|
+
// but encapsulating both outcomes in `ifTrue` resolves the union
|
|
113
|
+
Expect<Equal<R2, "Hello Joe">>
|
|
114
|
+
];
|
|
115
|
+
const cases: cases = [true, true];
|
|
116
|
+
});
|
|
117
|
+
|
|
53
118
|
it("ifUndefined(v,i,e)", () => {
|
|
54
119
|
const t = ifUndefined(undefined, 42, false);
|
|
55
120
|
const f = ifUndefined(false, "yikes", 42);
|
|
@@ -62,4 +127,95 @@ describe("runtime if/is", () => {
|
|
|
62
127
|
];
|
|
63
128
|
const cases: cases = [true, true, true];
|
|
64
129
|
});
|
|
130
|
+
|
|
131
|
+
it("StartsWith<T,U>", () => {
|
|
132
|
+
type T1 = StartsWith<"foobar", "foo">;
|
|
133
|
+
type T2 = StartsWith<"foobar", "foot">;
|
|
134
|
+
type T3 = StartsWith<"foobar", string>;
|
|
135
|
+
type T4 = StartsWith<string, "foo">;
|
|
136
|
+
type T5 = StartsWith<string, string>;
|
|
137
|
+
|
|
138
|
+
type cases = [
|
|
139
|
+
Expect<Equal<T1, true>>, //
|
|
140
|
+
Expect<Equal<T2, false>>,
|
|
141
|
+
Expect<Equal<T3, boolean>>,
|
|
142
|
+
Expect<Equal<T4, boolean>>,
|
|
143
|
+
Expect<Equal<T5, boolean>>
|
|
144
|
+
];
|
|
145
|
+
const cases: cases = [true, true, true, true, true];
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("EndsWith<T,U>", () => {
|
|
149
|
+
type T1 = EndsWith<"foobar", "bar">;
|
|
150
|
+
type T2 = EndsWith<"foobar", "bart">;
|
|
151
|
+
type T3 = EndsWith<"foobar", string>;
|
|
152
|
+
type T4 = EndsWith<string, "bar">;
|
|
153
|
+
type T5 = EndsWith<string, string>;
|
|
154
|
+
|
|
155
|
+
type cases = [
|
|
156
|
+
Expect<Equal<T1, true>>, //
|
|
157
|
+
Expect<Equal<T2, false>>,
|
|
158
|
+
Expect<Equal<T3, boolean>>,
|
|
159
|
+
Expect<Equal<T4, boolean>>,
|
|
160
|
+
Expect<Equal<T5, boolean>>
|
|
161
|
+
];
|
|
162
|
+
const cases: cases = [true, true, true, true, true];
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("startsWith(t)(v)", () => {
|
|
166
|
+
const t1 = startsWith("foo")("foobar");
|
|
167
|
+
const t2 = startsWith("foot")("foobar");
|
|
168
|
+
const p1 = startsWith("foo");
|
|
169
|
+
|
|
170
|
+
// runtime
|
|
171
|
+
expect(t1).toBe(true);
|
|
172
|
+
expect(t2).toBe(false);
|
|
173
|
+
expect(p1("foot")).toBe(true);
|
|
174
|
+
expect(p1("bart")).toBe(false);
|
|
175
|
+
|
|
176
|
+
// design time
|
|
177
|
+
type cases = [
|
|
178
|
+
Expect<Equal<typeof t1, true>>, //
|
|
179
|
+
Expect<Equal<typeof t2, false>> //
|
|
180
|
+
];
|
|
181
|
+
const cases: cases = [true, true];
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("ifStartsWith(start, isTrue, isFalse)(v)", () => {
|
|
185
|
+
const noSir = <T extends string>(i: T) => `no sir didn't like it ${i}` as const;
|
|
186
|
+
const startWithFoo = ifStartsWith(
|
|
187
|
+
// condition
|
|
188
|
+
"foo",
|
|
189
|
+
// inline
|
|
190
|
+
(i) => `welcome ${i}` as const,
|
|
191
|
+
// external
|
|
192
|
+
noSir
|
|
193
|
+
);
|
|
194
|
+
const t = startWithFoo("foobar");
|
|
195
|
+
type T = typeof t;
|
|
196
|
+
const f = startWithFoo("nope");
|
|
197
|
+
type F = typeof f;
|
|
198
|
+
|
|
199
|
+
type FS = typeof startWithFoo;
|
|
200
|
+
type RFS = ReturnType<FS>;
|
|
201
|
+
|
|
202
|
+
// runtime
|
|
203
|
+
expect(t).toBe("welcome foobar");
|
|
204
|
+
expect(f).toBe("no sir didn't like it nope");
|
|
205
|
+
|
|
206
|
+
// TODO: get the design time to be more literal
|
|
207
|
+
|
|
208
|
+
type cases = [
|
|
209
|
+
Expect<Equal<T, `welcome ${string}`>>,
|
|
210
|
+
Expect<Equal<F, `no sir didn't like it ${string}`>>,
|
|
211
|
+
Expect<
|
|
212
|
+
Equal<
|
|
213
|
+
//
|
|
214
|
+
RFS,
|
|
215
|
+
`welcome ${string}` | `no sir didn't like it ${string}`
|
|
216
|
+
>
|
|
217
|
+
>
|
|
218
|
+
];
|
|
219
|
+
const cases: cases = [true, true, true];
|
|
220
|
+
});
|
|
65
221
|
});
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
4
4
|
import { FunctionType } from "src/types";
|
|
5
|
-
import { type, createFnWithProps, isFunction, isObject } from "src/
|
|
5
|
+
import { type, createFnWithProps, isFunction, isObject } from "src/runtime";
|
|
6
6
|
|
|
7
7
|
describe("testing type() utility and some pre-made conditions", () => {
|
|
8
8
|
it("isFunction()", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { literal, strArrayToDict } from "../src/
|
|
3
|
+
import { literal, strArrayToDict } from "../src/runtime";
|
|
4
4
|
import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
|
|
5
5
|
|
|
6
6
|
describe("strArrayToDict() utility", () => {
|
package/tests/withValue.spec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
-
import { createFnWithProps, type, withValue } from "../src/
|
|
3
|
+
import { createFnWithProps, type, withValue } from "../src/runtime";
|
|
4
4
|
import { FunctionType, WithValue } from "../src";
|
|
5
5
|
|
|
6
6
|
describe("withValue()() utility", () => {
|
package/vitest.config.ts
CHANGED
|
@@ -6,15 +6,12 @@ import { resolve } from "pathe";
|
|
|
6
6
|
export default defineConfig({
|
|
7
7
|
resolve: {
|
|
8
8
|
alias: {
|
|
9
|
-
src: resolve(__dirname, "./src"),
|
|
10
|
-
test: resolve(__dirname, "./test"),
|
|
9
|
+
src: resolve(__dirname, "./src/"),
|
|
10
|
+
test: resolve(__dirname, "./test/"),
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
test: {
|
|
14
14
|
dir: "tests",
|
|
15
|
-
api: {
|
|
16
|
-
host: "0.0.0.0",
|
|
17
|
-
},
|
|
18
15
|
},
|
|
19
16
|
plugins: [],
|
|
20
17
|
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-use-before-define */
|
|
2
|
-
|
|
3
|
-
import { MutationIdentity } from "./MutationIdentity";
|
|
4
|
-
|
|
5
|
-
export type MutationFunction<T extends any, P extends any[]> = (...args: P) => T;
|
|
6
|
-
// export type MutationApi<A extends object, MutationFunction<T,P>> = {[key: U in A]: MutationFunction<T,P>}
|
|
7
|
-
// export type MutationApi<T extends any, K extends string & keyof A, A extends { [key: K]: MutationFunction<T,P>} =
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* **MutationFunction**
|
|
11
|
-
*
|
|
12
|
-
* Given a `MutationIdentity` higher-order function to work with, _this_ higher order expression
|
|
13
|
-
* allows you to specify the structure of "state" `T` with the first function call; the
|
|
14
|
-
* remaining function then serves as a strongly typed way to do partial application and get
|
|
15
|
-
* back just the _mutation function_ responsible for changing the state. The mutation function
|
|
16
|
-
* will take the form of:
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* const fn: (...args: P) => T = MutationFunction<T>()(mutationIdentity);
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export function createMutationFunction<T extends any>(state: T) {
|
|
23
|
-
return <M extends MutationIdentity<T, P>, P extends any[]>(mutationIdentity: M) => {
|
|
24
|
-
return mutationIdentity(state);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-use-before-define */
|
|
2
|
-
/**
|
|
3
|
-
* **MutationIdentity**
|
|
4
|
-
*
|
|
5
|
-
* Defines a function which is passed a state `T` and returns a function with
|
|
6
|
-
* an arbitrary -- but strongly typed -- set of parameters `P` which _must_ return
|
|
7
|
-
* the same state `T` back.
|
|
8
|
-
*
|
|
9
|
-
* This allows `T` to be mutated by a relatively unconstrained set of mutation functions with the
|
|
10
|
-
* sole guarentee that the form `T` is preserved.
|
|
11
|
-
*/
|
|
12
|
-
export type MutationIdentity<T, P extends any[]> = (state: T) => (...args: P) => T;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* **MutationIdentity**
|
|
16
|
-
*
|
|
17
|
-
* A function which strongly types the construction of a `MutationIdentity`
|
|
18
|
-
* higher-order function to be built. Usage:
|
|
19
|
-
*
|
|
20
|
-
* - The structure of the _state_ is defined in the first call as `T`
|
|
21
|
-
* - The interior function than defines a mutation function which implicitly
|
|
22
|
-
* defines the calling signature as `P` but is required to return the identity state
|
|
23
|
-
* structure `T`.
|
|
24
|
-
*
|
|
25
|
-
* ```ts
|
|
26
|
-
* type State = { foo: number, bar: number };
|
|
27
|
-
* const incr = MutationIdentity<State>()(
|
|
28
|
-
* s => () => {...s, foo: s.foo++}
|
|
29
|
-
* );
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
export function MutationIdentity<T>() {
|
|
33
|
-
return function <M extends MutationIdentity<T, P>, P extends any[]>(m: M) {
|
|
34
|
-
return m;
|
|
35
|
-
};
|
|
36
|
-
}
|
package/src/Mutation/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// #autoindex
|
|
2
|
-
|
|
3
|
-
// #region auto-indexed files
|
|
4
|
-
// index last changed at: 8th Aug, 2022, 09:51 AM ( GMT-7 )
|
|
5
|
-
// hash-code: bd3a442e
|
|
6
|
-
|
|
7
|
-
// file exports
|
|
8
|
-
export * from "./MutationFunction";
|
|
9
|
-
export * from "./MutationIdentity";
|
|
10
|
-
|
|
11
|
-
// #endregion auto-indexed files
|
|
12
|
-
|
|
13
|
-
// see https://github.com/inocan-group/do-devops/docs/autoindex.md
|
|
14
|
-
// for more info
|
package/src/shared/README.md
DELETED
package/src/shared/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// #autoindex: orphan
|
|
2
|
-
|
|
3
|
-
// #region auto-indexed files
|
|
4
|
-
// index last changed at: 8th Aug, 2022, 09:51 AM ( GMT-7 )
|
|
5
|
-
// hash-code: 3305143b
|
|
6
|
-
|
|
7
|
-
// file exports
|
|
8
|
-
export * from "./randomString";
|
|
9
|
-
export * from "./uuid";
|
|
10
|
-
export * from "./valueTypes";
|
|
11
|
-
|
|
12
|
-
// #endregion auto-indexed files
|
|
13
|
-
|
|
14
|
-
// see https://github.com/inocan-group/do-devops/docs/autoindex.md
|
|
15
|
-
// for more info
|
package/src/shared/uuid.ts
DELETED
package/src/types/First.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// #autoindex, exclude: IoModel
|
|
2
|
-
// #region auto-indexed files
|
|
3
|
-
// index last changed at: 8th Aug, 2022, 09:51 AM ( GMT-7 )
|
|
4
|
-
// hash-code: db68628c
|
|
5
|
-
|
|
6
|
-
// file exports
|
|
7
|
-
export * from "./Model";
|
|
8
|
-
|
|
9
|
-
// #endregion auto-indexed files
|
|
10
|
-
|
|
11
|
-
// see https://github.com/inocan-group/do-devops/docs/autoindex.md
|
|
12
|
-
// for more info
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
|
|
3
|
-
import { MutationIdentity } from "../src/Mutation";
|
|
4
|
-
import type { Expect, Equal, ExpectExtends } from "@type-challenges/utils";
|
|
5
|
-
|
|
6
|
-
describe("MutationIdentity type", () => {
|
|
7
|
-
it("MutationIdentity provides properly typed higher-order function", () => {
|
|
8
|
-
type State = { foo: number; bar: number };
|
|
9
|
-
const t1 = MutationIdentity<State>()((s) => () => s);
|
|
10
|
-
const t2 = MutationIdentity<State>()((s) => (foo: number) => ({
|
|
11
|
-
...s,
|
|
12
|
-
foo,
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
type cases = [
|
|
16
|
-
Expect<ExpectExtends<MutationIdentity<State, any>, typeof t1>>,
|
|
17
|
-
Expect<ExpectExtends<MutationIdentity<State, any>, typeof t2>>,
|
|
18
|
-
Expect<Equal<MutationIdentity<State, []>, typeof t1>>,
|
|
19
|
-
Expect<Equal<MutationIdentity<State, [number]>, typeof t2>>
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
const expected: cases = [true, true, true, true];
|
|
23
|
-
expect(expected).toBe(expected);
|
|
24
|
-
});
|
|
25
|
-
});
|