inferred-types 0.19.0 → 0.22.0
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/.eslintrc +36 -20
- package/.github/workflows/main.yml +34 -0
- package/.github/workflows/other.yml +15 -0
- package/.vscode/settings.json +10 -2
- package/dist/index.d.ts +403 -8538
- package/dist/index.js +35 -60
- package/dist/index.mjs +24 -48
- package/package.json +34 -23
- package/src/shared/valueTypes.ts +1 -1
- package/src/types/ExpandRecursively.ts +10 -1
- package/src/types/FunctionType.ts +1 -1
- package/src/types/SimplifyObject.ts +12 -0
- package/src/types/Transformer.ts +1 -1
- package/src/types/alphabetic/CamelCase.ts +1 -1
- package/src/types/alphabetic/CapFirstAlpha.ts +7 -3
- package/src/types/alphabetic/Dasherize.ts +8 -5
- package/src/types/alphabetic/KebabCase.ts +1 -1
- package/src/types/alphabetic/PascalCase.ts +3 -1
- package/src/types/alphabetic/SnakeCase.ts +8 -3
- package/src/types/dictionary/DictPartialApplication.ts +30 -0
- package/src/types/dictionary/DictPrependWithFn.ts +23 -0
- package/src/types/dictionary/DictReturnValues.ts +27 -0
- package/src/types/dictionary/RequireProps.ts +15 -0
- package/src/types/{type-conversion → dictionary}/SameKeys.ts +0 -0
- package/src/types/dictionary/index.ts +8 -3
- package/src/types/{props.ts → dictionary/props.ts} +1 -1
- package/src/types/functions/FinalReturn.ts +12 -0
- package/{on-hold/types → src/types/functions}/index.ts +4 -3
- package/src/types/index.ts +4 -3
- package/src/types/ruleset-types.ts +3 -3
- package/src/types/runtime.ts +18 -18
- package/src/types/string-literals/LeftWhitespace.ts +5 -2
- package/src/types/string-literals/RightWhitespace.ts +5 -2
- package/src/types/tuples/FirstKey.ts +3 -3
- package/src/types/tuples/FromDictArray.ts +5 -4
- package/src/types/type-conversion/index.ts +2 -5
- package/src/utility/api/api.ts +8 -7
- package/src/utility/createFnWithProps.ts +26 -1
- package/src/utility/dictionary/dictionaryTransform.ts +5 -4
- package/src/utility/dictionary/entries.ts +9 -5
- package/src/utility/dictionary/index.ts +2 -3
- package/src/utility/dictionary/kv/dictToKv.ts +5 -3
- package/src/utility/dictionary/kv/filterDictArray.ts +5 -7
- package/src/utility/dictionary/kv/kv.ts +8 -3
- package/src/utility/dictionary/kv/kvToDict.ts +3 -2
- package/src/utility/dictionary/mapValues.ts +8 -5
- package/src/utility/dictionary/strArrayToDict.ts +1 -2
- package/src/utility/keys.ts +8 -4
- package/src/utility/lists/groupBy.ts +2 -9
- package/src/utility/literals/arrayToObject.ts +29 -29
- package/src/utility/literals/defineType.ts +6 -6
- package/src/utility/literals/identity.ts +5 -2
- package/src/utility/literals/literal.ts +3 -3
- package/src/utility/ruleset.ts +11 -9
- package/src/utility/runtime/condition.ts +1 -1
- package/src/utility/runtime/conditions/isFalse.ts +2 -2
- package/src/utility/runtime/conditions/isFunction.ts +2 -2
- package/src/utility/runtime/conditions/isObject.ts +4 -1
- package/src/utility/runtime/conditions/isTrue.ts +1 -1
- package/src/utility/runtime/ifTypeOf.ts +1 -1
- package/src/utility/runtime/type.ts +3 -1
- package/src/utility/runtime/withValue.ts +5 -3
- package/src/utility/state/Configurator.ts +2 -2
- package/src/utility/state/FluentConfigurator.ts +2 -2
- package/src/utility/state/index.ts +2 -3
- package/tests/CamelCase-spec.ts +2 -0
- package/tests/ExplicitFunction-spec.ts +3 -2
- package/tests/IncludeAndRetain-spec.ts +7 -12
- package/tests/Includes-spec.ts +2 -0
- package/tests/KebabCase-spec.ts +2 -0
- package/tests/MutationIdentity-spec.ts +2 -1
- package/tests/PascalCase-spec.ts +2 -0
- package/tests/Pluralize-spec.ts +2 -0
- package/tests/SnakeCase-spec.ts +2 -0
- package/tests/Where.spec.ts +9 -10
- package/tests/arrayToKeyLookup-spec.ts +5 -5
- package/tests/arrayToObject-spec.ts +12 -8
- package/tests/constructor.spec.ts +2 -0
- package/tests/createFnWithProps.spec.ts +2 -2
- package/tests/defineType-spec.ts +17 -11
- package/tests/dictionary/DictPartialApplication.test.ts +43 -0
- package/tests/dictionary/DictReturnValues.test.ts +32 -0
- package/tests/dictionary/Get.spec.ts +5 -3
- package/tests/dictionary/PrependValuesWithFunction.ts +34 -0
- package/tests/dictionary/RequireProps.test.ts +21 -0
- package/tests/dictionaryTransform-spec.ts +3 -3
- package/tests/ifTypeOf-spec.ts +31 -20
- package/tests/kv/KeyValue-spec.ts +4 -4
- package/tests/kv/SameKeys-spec.ts +6 -9
- package/tests/kv/dict-to-kv-and-back.spec.ts +5 -4
- package/tests/kv/entries-spec.ts +8 -9
- package/tests/kv/keys.spec.ts +9 -19
- package/tests/kv/kv-spec.ts +4 -4
- package/tests/lists/UniqueForProp.spec.ts +3 -1
- package/tests/literal-spec.ts +5 -3
- package/tests/mapValues-spec.ts +5 -3
- package/tests/props-spec.ts +3 -2
- package/tests/runtime/condition.spec.ts +2 -1
- package/tests/runtime/type.spec.ts +4 -3
- package/tests/strArrayToDict-spec.ts +6 -6
- package/tests/string-literals/AllCaps.spec.ts +6 -15
- package/tests/string-literals/CamelCase.spec.ts +13 -32
- package/tests/string-literals/Dasherize.spec.ts +13 -31
- package/tests/string-literals/HasUppercase.spec.ts +6 -15
- package/tests/string-literals/PascalCase.spec.ts +13 -32
- package/tests/string-literals/SnakeCase.spec.ts +13 -32
- package/tests/string-literals/whitespace-capture.spec.ts +10 -28
- package/tests/tuples/TupleToUnion.spec.ts +3 -1
- package/tests/withValue.spec.ts +4 -3
- package/tsconfig.json +8 -19
- package/vitest.config.ts +13 -0
- package/jest.config.ts +0 -20
- package/on-hold/Builder/Builder.ts +0 -66
- package/on-hold/Builder/BuilderApi.ts +0 -21
- package/on-hold/Builder/IdentityToMutationApi.ts +0 -44
- package/on-hold/Builder/MutationToFluentApi.ts +0 -60
- package/on-hold/Builder/index.ts +0 -35
- package/on-hold/tests/Builder-spec.ts +0 -310
- package/on-hold/tests/RuleSet-spec.ts +0 -59
- package/on-hold/tests/ToFluent-spec.ts +0 -60
- package/on-hold/tests/api-spec.ts +0 -73
- package/on-hold/tests/data/builder-data.ts +0 -53
- package/on-hold/tests/filterDictArray-spec.ts +0 -50
- package/on-hold/tests/run-time-spec.ts +0 -44
- package/on-hold/type.ts +0 -20
- package/on-hold/types/object.ts +0 -19
- package/on-hold/types/prop.ts +0 -28
- package/on-hold/types/scalar.ts +0 -37
- package/src/types/dictionary/NotEmptyObject.ts +0 -9
- package/src/types/type-conversion/UnwrapValue.ts +0 -13
- package/src/types/type-conversion/WrapValue.ts +0 -15
- package/src/utility/dictionary/valuesOfProp.ts +0 -13
- package/src/utility/state/KeyStorage.ts +0 -23
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { DictPartialApplication } from "src/types";
|
|
4
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
5
|
+
|
|
6
|
+
describe("DictUnwrapValues<T>", () => {
|
|
7
|
+
it("happy path", () => {
|
|
8
|
+
const api = {
|
|
9
|
+
hi: (name: string) => `hi ${name}`,
|
|
10
|
+
bye: (name: string) => `bye ${name}`,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type Api = typeof api;
|
|
14
|
+
type T = DictPartialApplication<Api>;
|
|
15
|
+
type Expected = { hi: string; bye: string };
|
|
16
|
+
|
|
17
|
+
type cases = [Expect<Equal<T, Expected>>];
|
|
18
|
+
|
|
19
|
+
const cases: cases = [true];
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("object which has non-function based props", () => {
|
|
23
|
+
const api = {
|
|
24
|
+
theAnswer: 42,
|
|
25
|
+
hi: (name: string) => `hi ${name}`,
|
|
26
|
+
bye: (name: string) => `bye ${name}`,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type Api = typeof api;
|
|
30
|
+
type T1 = DictPartialApplication<Api>;
|
|
31
|
+
type T2 = DictPartialApplication<Api, true>;
|
|
32
|
+
type T3 = DictPartialApplication<Api, false>;
|
|
33
|
+
type Expected = { hi: string; bye: string };
|
|
34
|
+
type Expected3 = { theAnswer: number; hi: string; bye: string };
|
|
35
|
+
|
|
36
|
+
type cases = [
|
|
37
|
+
Expect<Equal<T1, Expected>>,
|
|
38
|
+
Expect<Equal<T2, Expected>>,
|
|
39
|
+
Expect<Equal<T3, Expected3>>
|
|
40
|
+
];
|
|
41
|
+
const cases: cases = [true, true, true];
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { DictReturnValues } from "src/types";
|
|
4
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
5
|
+
|
|
6
|
+
describe("DictReturnValues<T, R, O>", () => {
|
|
7
|
+
it("happy path", () => {
|
|
8
|
+
const api = {
|
|
9
|
+
foo: (name: string) => `${name}`,
|
|
10
|
+
multiply: (v1: number, v2: number) => v1 * v2,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type Api = typeof api;
|
|
14
|
+
// convert all functions
|
|
15
|
+
type T1 = DictReturnValues<Api, null>;
|
|
16
|
+
// convert functions with `number` return
|
|
17
|
+
type T2 = DictReturnValues<Api, null, (...args: any[]) => number>;
|
|
18
|
+
|
|
19
|
+
type Expected1 = {
|
|
20
|
+
foo: (name: string) => null;
|
|
21
|
+
multiply: (v1: number, v2: number) => null;
|
|
22
|
+
};
|
|
23
|
+
type Expected2 = {
|
|
24
|
+
foo: (name: string) => string;
|
|
25
|
+
multiply: (v1: number, v2: number) => null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type cases = [Expect<Equal<T1, Expected1>>, Expect<Equal<T2, Expected2>>];
|
|
29
|
+
|
|
30
|
+
const cases: cases = [true, true];
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
2
|
-
import { Get } from "
|
|
3
|
-
import { defineType } from "
|
|
4
|
+
import { Get } from "src/types";
|
|
5
|
+
import { defineType } from "src/utility";
|
|
4
6
|
|
|
5
7
|
describe("Get<T, K> type utility", () => {
|
|
6
8
|
it("Get<T,K> works with literals and wide types", () => {
|
|
@@ -17,7 +19,7 @@ describe("Get<T, K> type utility", () => {
|
|
|
17
19
|
Expect<Equal<Id, 1234>>,
|
|
18
20
|
Expect<Equal<Foo, number>>,
|
|
19
21
|
Expect<Equal<Bar, string>>,
|
|
20
|
-
// non-
|
|
22
|
+
// non-existent props return never
|
|
21
23
|
Expect<Equal<Nada, never>>
|
|
22
24
|
];
|
|
23
25
|
const c: cases = [true, true, true, true];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { DictPrependWithFn } from "src/types";
|
|
4
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
5
|
+
|
|
6
|
+
describe("WrapValuesWithFunction<T, R, O>", () => {
|
|
7
|
+
it("happy path", () => {
|
|
8
|
+
const api = {
|
|
9
|
+
static: 42,
|
|
10
|
+
foo: (name: string) => `${name}`,
|
|
11
|
+
multiply: (v1: number, v2: number) => v1 * v2,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Api = typeof api;
|
|
15
|
+
type T1 = DictPrependWithFn<Api, [name: string, age: number]>;
|
|
16
|
+
type T2 = DictPrependWithFn<Api, [name: string, age: number], Function>;
|
|
17
|
+
|
|
18
|
+
type Expected1 = {
|
|
19
|
+
static: (name: string, age: number) => number;
|
|
20
|
+
foo: (name: string, age: number) => (name: string) => string;
|
|
21
|
+
multiply: (name: string, age: number) => (v1: number, v2: number) => number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type Expected2 = {
|
|
25
|
+
static: number;
|
|
26
|
+
foo: (name: string, age: number) => (name: string) => string;
|
|
27
|
+
multiply: (name: string, age: number) => (v1: number, v2: number) => number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type cases = [Expect<Equal<T1, Expected1>>, Expect<Equal<T2, Expected2>>];
|
|
31
|
+
const cases: cases = [true, true];
|
|
32
|
+
expect(cases).toBe(cases);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
+
|
|
4
|
+
import { RequireProps } from "src/types/dictionary";
|
|
5
|
+
|
|
6
|
+
describe("RequireProps<T,R>", () => {
|
|
7
|
+
it("works as expected", () => {
|
|
8
|
+
type Start = { foo?: string; bar?: number };
|
|
9
|
+
type Foo = RequireProps<Start, "foo">;
|
|
10
|
+
type Bar = RequireProps<Start, "bar">;
|
|
11
|
+
type Both = RequireProps<Start, "foo" | "bar">;
|
|
12
|
+
|
|
13
|
+
type cases = [
|
|
14
|
+
Expect<Equal<Foo, { foo: string; bar?: number }>>,
|
|
15
|
+
Expect<Equal<Bar, { foo?: string; bar: number }>>,
|
|
16
|
+
Expect<Equal<Both, { foo: string; bar: number }>>
|
|
17
|
+
];
|
|
18
|
+
const cases: cases = [true, true, true];
|
|
19
|
+
expect(cases).toBe(cases);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { dictionaryTransform, ExplicitFunction } from "
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { dictionaryTransform, ExplicitFunction } from "../src/utility";
|
|
3
3
|
import { Expect, Equal, NotEqual, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
|
|
4
|
-
import { ToFluent, Transformer } from "
|
|
4
|
+
import { ToFluent, Transformer } from "../src/types";
|
|
5
5
|
|
|
6
6
|
describe("dictionaryTransform()", () => {
|
|
7
7
|
type A = { foo: string; bar: string };
|
package/tests/ifTypeOf-spec.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
4
|
import { Expect, Equal } from "@type-challenges/utils";
|
|
4
|
-
import { ifTypeOf, defineType, literal } from "
|
|
5
|
+
import { ifTypeOf, defineType, literal } from "../src/utility";
|
|
5
6
|
|
|
6
7
|
describe("ifTypeOf() utility", () => {
|
|
7
8
|
it("base validation with extends() returns true/false", () => {
|
|
@@ -12,10 +13,7 @@ describe("ifTypeOf() utility", () => {
|
|
|
12
13
|
expect(yup).toBe(true);
|
|
13
14
|
expect(nope).toBe(false);
|
|
14
15
|
|
|
15
|
-
type cases = [
|
|
16
|
-
Expect<Equal<typeof yup, true>>,
|
|
17
|
-
Expect<Equal<typeof nope, false>>,
|
|
18
|
-
];
|
|
16
|
+
type cases = [Expect<Equal<typeof yup, true>>, Expect<Equal<typeof nope, false>>];
|
|
19
17
|
const cases: cases = [true, true];
|
|
20
18
|
expect(cases).toBe(cases);
|
|
21
19
|
});
|
|
@@ -36,7 +34,7 @@ describe("ifTypeOf() utility", () => {
|
|
|
36
34
|
Expect<Equal<typeof yup, true>>,
|
|
37
35
|
Expect<Equal<typeof yup2, true>>,
|
|
38
36
|
Expect<Equal<typeof nope1, false>>,
|
|
39
|
-
Expect<Equal<typeof nope2, false
|
|
37
|
+
Expect<Equal<typeof nope2, false>>
|
|
40
38
|
];
|
|
41
39
|
const cases: cases = [true, true, true, true];
|
|
42
40
|
expect(cases).toBe(cases);
|
|
@@ -63,7 +61,7 @@ describe("ifTypeOf() utility", () => {
|
|
|
63
61
|
Expect<Equal<typeof wideNumCompare, true>>,
|
|
64
62
|
Expect<Equal<typeof narrowEquality, true>>,
|
|
65
63
|
Expect<Equal<typeof stringIsNumber, false>>,
|
|
66
|
-
Expect<Equal<typeof diffNumbersNarrowly, false
|
|
64
|
+
Expect<Equal<typeof diffNumbersNarrowly, false>>
|
|
67
65
|
];
|
|
68
66
|
const cases: cases = [true, true, true, true, true];
|
|
69
67
|
expect(cases).toBe(cases);
|
|
@@ -76,25 +74,41 @@ describe("ifTypeOf() utility", () => {
|
|
|
76
74
|
|
|
77
75
|
expect(fnExtends).toBe(true);
|
|
78
76
|
|
|
79
|
-
type cases = [
|
|
80
|
-
Expect<Equal<typeof fnExtends, true>>
|
|
81
|
-
];
|
|
77
|
+
type cases = [Expect<Equal<typeof fnExtends, true>>];
|
|
82
78
|
const cases: cases = [true];
|
|
83
79
|
expect(cases).toBe(cases);
|
|
84
80
|
});
|
|
85
81
|
|
|
86
82
|
it("checklist example", () => {
|
|
87
|
-
const noFoodOrDrink = ifTypeOf({ wakeUp: true }).extends({
|
|
88
|
-
|
|
83
|
+
const noFoodOrDrink = ifTypeOf({ wakeUp: true }).extends({
|
|
84
|
+
wakeUp: true,
|
|
85
|
+
eatBreakfast: true,
|
|
86
|
+
drinkCoffee: true,
|
|
87
|
+
});
|
|
88
|
+
const ready = ifTypeOf({ wakeUp: true, eatBreakfast: true, drinkCoffee: true }).extends({
|
|
89
|
+
wakeUp: true,
|
|
90
|
+
eatBreakfast: true,
|
|
91
|
+
drinkCoffee: true,
|
|
92
|
+
});
|
|
89
93
|
|
|
90
94
|
// completely wrong
|
|
91
|
-
const fullyBaked = ifTypeOf({ wakeUp: false, eatBreakfast: false, drinkCoffee: false }).extends(
|
|
95
|
+
const fullyBaked = ifTypeOf({ wakeUp: false, eatBreakfast: false, drinkCoffee: false }).extends(
|
|
96
|
+
{ wakeUp: true, eatBreakfast: true, drinkCoffee: true }
|
|
97
|
+
);
|
|
92
98
|
|
|
93
99
|
// half-right
|
|
94
|
-
const halfBaked = ifTypeOf({ wakeUp: false, eatBreakfast: false, drinkCoffee: false }).extends({
|
|
100
|
+
const halfBaked = ifTypeOf({ wakeUp: false, eatBreakfast: false, drinkCoffee: false }).extends({
|
|
101
|
+
wakeUp: true,
|
|
102
|
+
eatBreakfast: true,
|
|
103
|
+
drinkCoffee: true,
|
|
104
|
+
} as const);
|
|
95
105
|
|
|
96
106
|
// back to right; at the cost of being very careful
|
|
97
|
-
const lucid = ifTypeOf({
|
|
107
|
+
const lucid = ifTypeOf({
|
|
108
|
+
wakeUp: false,
|
|
109
|
+
eatBreakfast: false,
|
|
110
|
+
drinkCoffee: false,
|
|
111
|
+
}).narrowlyExtends({ wakeUp: true, eatBreakfast: true, drinkCoffee: true } as const);
|
|
98
112
|
|
|
99
113
|
// run-time tests of False Positives
|
|
100
114
|
// ---------------------------------
|
|
@@ -157,7 +171,6 @@ describe("ifTypeOf() utility", () => {
|
|
|
157
171
|
const fn2 = (_c: number) => "string";
|
|
158
172
|
const genericFn: Function = () => "string";
|
|
159
173
|
|
|
160
|
-
|
|
161
174
|
try {
|
|
162
175
|
const narrow = ifTypeOf(fn).narrowlyExtends(fn2);
|
|
163
176
|
const asWellAsGeneric = ifTypeOf(fn).narrowlyExtends(genericFn);
|
|
@@ -172,8 +185,6 @@ describe("ifTypeOf() utility", () => {
|
|
|
172
185
|
} catch {
|
|
173
186
|
// there is no way to narrow compare functions and so it throws
|
|
174
187
|
// an error to the run time system
|
|
175
|
-
}
|
|
176
|
-
|
|
188
|
+
}
|
|
177
189
|
});
|
|
178
190
|
});
|
|
179
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
2
|
-
import { KeyValue } from "
|
|
4
|
+
import { KeyValue } from "src/types";
|
|
3
5
|
|
|
4
6
|
describe("KeyValue<T, K> type utility", () => {
|
|
5
|
-
|
|
6
7
|
it("explicit KeyValue<T,K> definitions retain literal type info", () => {
|
|
7
8
|
const obj = { foo: 1, bar: "hi", baz: { a: 1, b: 2 } } as const;
|
|
8
9
|
type O = typeof obj;
|
|
@@ -13,10 +14,9 @@ describe("KeyValue<T, K> type utility", () => {
|
|
|
13
14
|
type cases = [
|
|
14
15
|
Expect<Equal<Foo, ["foo", 1]>>,
|
|
15
16
|
Expect<Equal<Bar, ["bar", "hi"]>>,
|
|
16
|
-
Expect<Equal<Baz, ["baz", { readonly a: 1; readonly b: 2 }]
|
|
17
|
+
Expect<Equal<Baz, ["baz", { readonly a: 1; readonly b: 2 }]>>
|
|
17
18
|
];
|
|
18
19
|
const c: cases = [true, true, true];
|
|
19
20
|
expect(c).toBe(c);
|
|
20
21
|
});
|
|
21
|
-
|
|
22
22
|
});
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Equal, Expect, ExpectFalse } from "@type-challenges/utils";
|
|
2
|
-
import { SameKeys } from "
|
|
4
|
+
import { SameKeys } from "src/types";
|
|
3
5
|
|
|
4
6
|
describe("SameKeys<T> utility", () => {
|
|
5
|
-
|
|
6
7
|
it("keys must be same type but value can be anything", () => {
|
|
7
8
|
const origin = { id: "abc", favorite: false };
|
|
8
9
|
type O = typeof origin;
|
|
9
10
|
type SK = SameKeys<O>;
|
|
10
11
|
|
|
11
|
-
type cases = [
|
|
12
|
-
Expect<Equal<SK, { id: any; favorite: any }>>
|
|
13
|
-
];
|
|
12
|
+
type cases = [Expect<Equal<SK, { id: any; favorite: any }>>];
|
|
14
13
|
const c: cases = [true];
|
|
15
14
|
expect(c).toBe(c);
|
|
16
|
-
|
|
17
15
|
});
|
|
18
16
|
|
|
19
17
|
it("explicit assignment does enforce exhaustion of all keys", () => {
|
|
@@ -27,12 +25,11 @@ describe("SameKeys<T> utility", () => {
|
|
|
27
25
|
// does not reach equality
|
|
28
26
|
ExpectFalse<Equal<SameKeys<O>, SameKeys<P>>>,
|
|
29
27
|
// but more importantly P can not be assigned to SameKeys<O>
|
|
30
|
-
// this ensures that you'd get a type error with:
|
|
28
|
+
// this ensures that you'd get a type error with:
|
|
31
29
|
// `const p: SameKeys<O> = { id: "abc" }`
|
|
32
|
-
ExpectFalse<Equal<SameKeys<O>, P
|
|
30
|
+
ExpectFalse<Equal<SameKeys<O>, P>>
|
|
33
31
|
];
|
|
34
32
|
const c: cases = [false, false];
|
|
35
33
|
expect(c).toBe(c);
|
|
36
34
|
});
|
|
37
|
-
|
|
38
35
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Equal, Expect, NotEqual } from "@type-challenges/utils";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { dictToKv, kvToDict } from "src/utility/dictionary";
|
|
5
|
+
import { DictFromKv } from "src/types/kv";
|
|
6
|
+
import { keys } from "src/utility";
|
|
5
7
|
|
|
6
8
|
describe("dictToKv()", () => {
|
|
7
9
|
it.skip("basic structure is correct when forcing to Tuple structure", () => {
|
|
8
10
|
const obj = { id: 123, foo: "bar" } as const;
|
|
9
11
|
const val = dictToKv(obj, true);
|
|
10
|
-
// type Val = typeof val;
|
|
11
12
|
|
|
12
13
|
expect(Array.isArray(val)).toBeTruthy();
|
|
13
14
|
expect(val).toHaveLength(2);
|
package/tests/kv/entries-spec.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import type { Expect, NotEqual, Equal, ExpectExtends } from "@type-challenges/utils";
|
|
2
|
-
import { entries } from "
|
|
4
|
+
import { entries } from "src/utility";
|
|
3
5
|
|
|
4
6
|
describe("entries() => ", () => {
|
|
5
7
|
it("literal types are retained", () => {
|
|
@@ -25,9 +27,9 @@ describe("entries() => ", () => {
|
|
|
25
27
|
// inside a conditional, typescript knows as an
|
|
26
28
|
// explicit type and no longer a union of keys
|
|
27
29
|
Expect<Equal<typeof k, "foo">>,
|
|
28
|
-
// but the value is still a union of all KV
|
|
29
|
-
// values which makes it far less
|
|
30
|
-
Expect<Equal<typeof v, Value
|
|
30
|
+
// but the value is still a union of all KV
|
|
31
|
+
// values which makes it far less valuable
|
|
32
|
+
Expect<Equal<typeof v, Value>>
|
|
31
33
|
];
|
|
32
34
|
const c: cases2 = [true, true];
|
|
33
35
|
expect(c).toBe(c);
|
|
@@ -43,17 +45,14 @@ describe("entries() => ", () => {
|
|
|
43
45
|
// // inside a conditional, typescript knows as an
|
|
44
46
|
// // explicit type and no longer a union of keys
|
|
45
47
|
// Expect<Equal<typeof entry[0], "foo">>,
|
|
46
|
-
// // but the value is still a union of all KV
|
|
47
|
-
// // values which makes it far less
|
|
48
|
+
// // but the value is still a union of all KV
|
|
49
|
+
// // values which makes it far less valuable
|
|
48
50
|
// Expect<Equal<typeof v, Value>>,
|
|
49
51
|
// ];
|
|
50
52
|
// const c: cases3 = [true, true];
|
|
51
53
|
// expect(c).toBe(c);
|
|
52
54
|
// }
|
|
53
55
|
// }
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
56
|
});
|
|
58
57
|
|
|
59
58
|
it("values maintain their implicit type even when nested objects", () => {
|
package/tests/kv/keys.spec.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { Keys } from "src/types/Keys";
|
|
2
4
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
-
import { defineType, keys } from "
|
|
5
|
+
import { defineType, keys } from "src/utility";
|
|
4
6
|
|
|
5
7
|
describe("Keys<T>", () => {
|
|
6
8
|
it("Keys<T> is shorthand for keyof T", () => {
|
|
@@ -18,9 +20,7 @@ describe("Keys<T>", () => {
|
|
|
18
20
|
type Arr = typeof arr;
|
|
19
21
|
type MyKeys = Keys<Arr>;
|
|
20
22
|
|
|
21
|
-
type cases = [
|
|
22
|
-
Expect<Equal<MyKeys, "foo" | "bar">>
|
|
23
|
-
];
|
|
23
|
+
type cases = [Expect<Equal<MyKeys, "foo" | "bar">>];
|
|
24
24
|
const cases: cases = [true];
|
|
25
25
|
expect(cases).toBe(cases);
|
|
26
26
|
});
|
|
@@ -31,17 +31,13 @@ describe("Keys<T>", () => {
|
|
|
31
31
|
type OKeys = Keys<typeof obj, "foo">;
|
|
32
32
|
type OArr = Keys<typeof arr, "foo">;
|
|
33
33
|
|
|
34
|
-
type cases = [
|
|
35
|
-
Expect<Equal<OKeys, "bar">>,
|
|
36
|
-
Expect<Equal<OArr, "bar">>
|
|
37
|
-
];
|
|
34
|
+
type cases = [Expect<Equal<OKeys, "bar">>, Expect<Equal<OArr, "bar">>];
|
|
38
35
|
const cases: cases = [true, true];
|
|
39
36
|
expect(cases).toBe(cases);
|
|
40
37
|
});
|
|
41
38
|
});
|
|
42
39
|
|
|
43
40
|
describe("keys() utility", () => {
|
|
44
|
-
|
|
45
41
|
it("with just object passed in, keys are extracted as expected", () => {
|
|
46
42
|
const obj = defineType({ id: "123" })({ color: "red", isFavorite: false });
|
|
47
43
|
const k = keys(obj);
|
|
@@ -51,9 +47,7 @@ describe("keys() utility", () => {
|
|
|
51
47
|
expect(k).toContain("color");
|
|
52
48
|
expect(k).toContain("isFavorite");
|
|
53
49
|
|
|
54
|
-
type cases = [
|
|
55
|
-
Expect<Equal<typeof k, ("color" | "id" | "isFavorite")[]>>
|
|
56
|
-
];
|
|
50
|
+
type cases = [Expect<Equal<typeof k, ("color" | "id" | "isFavorite")[]>>];
|
|
57
51
|
const cases: cases = [true];
|
|
58
52
|
expect(cases).toBe(cases);
|
|
59
53
|
});
|
|
@@ -65,12 +59,8 @@ describe("keys() utility", () => {
|
|
|
65
59
|
expect(k).toHaveLength(1);
|
|
66
60
|
expect(k).toContain("isFavorite");
|
|
67
61
|
|
|
68
|
-
type cases = [
|
|
69
|
-
Expect<Equal<typeof k, ("isFavorite")[]>>
|
|
70
|
-
];
|
|
62
|
+
type cases = [Expect<Equal<typeof k, "isFavorite"[]>>];
|
|
71
63
|
const cases: cases = [true];
|
|
72
64
|
expect(cases).toBe(cases);
|
|
73
65
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
});
|
|
66
|
+
});
|
package/tests/kv/kv-spec.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { keys, kv } from "src/utility";
|
|
4
4
|
|
|
5
|
+
describe("kv utils", () => {
|
|
5
6
|
it("simple assignment works with strong literal support", () => {
|
|
6
7
|
const t1 = kv("foo", { a: 1, b: 2, c: "hi" });
|
|
7
8
|
const t2 = kv("bar", true);
|
|
@@ -16,5 +17,4 @@ describe("kv utils", () => {
|
|
|
16
17
|
expect(keys(t2)).toContain("bar");
|
|
17
18
|
expect(t2.bar).toBe(true);
|
|
18
19
|
});
|
|
19
|
-
|
|
20
|
-
});
|
|
20
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Expect, Equal, ExpectExtends } from "@type-challenges/utils";
|
|
2
|
-
import { UniqueForProp } from "
|
|
4
|
+
import { UniqueForProp } from "src/types/lists";
|
|
3
5
|
|
|
4
6
|
describe("UniqueForProp<T, P>", () => {
|
|
5
7
|
it("pull off uniques for 'id' prop", () => {
|
package/tests/literal-spec.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { idLiteral, literal } from "../src/utility";
|
|
2
4
|
import { Equal, NotEqual, Expect, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
|
|
3
5
|
|
|
4
6
|
describe("literal enforcement", () => {
|
|
@@ -57,8 +59,8 @@ describe("literal enforcement", () => {
|
|
|
57
59
|
/** but with the literal function we can force this to narrow */
|
|
58
60
|
const narrow = literal({ foo: 1, bar: false, baz: "hi" });
|
|
59
61
|
type Narrow = typeof narrow;
|
|
60
|
-
/**
|
|
61
|
-
* would be nice if this worked but it doesn't; once the type is set, it's set
|
|
62
|
+
/**
|
|
63
|
+
* would be nice if this worked but it doesn't; once the type is set, it's set
|
|
62
64
|
*/
|
|
63
65
|
const nope = literal(wide);
|
|
64
66
|
type Nope = typeof nope;
|
package/tests/mapValues-spec.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { mapValues, literal } from "../src/utility";
|
|
2
4
|
import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
|
|
3
5
|
|
|
4
6
|
describe("mapValues() utility", () => {
|
|
5
7
|
it("simple transform while maintaining wide type through transform", () => {
|
|
6
8
|
const colors = { red: 4, blue: 2, green: 3 };
|
|
7
|
-
const x2 = mapValues(colors, v => v * 2);
|
|
9
|
+
const x2 = mapValues(colors, (v) => v * 2);
|
|
8
10
|
|
|
9
11
|
expect(x2.red).toBe(colors.red * 2);
|
|
10
12
|
expect(x2.blue).toBe(colors.blue * 2);
|
|
@@ -25,7 +27,7 @@ describe("mapValues() utility", () => {
|
|
|
25
27
|
|
|
26
28
|
it("simple transform but with input type set to literals", () => {
|
|
27
29
|
const colors = literal({ red: 4, blue: 2, green: 3 });
|
|
28
|
-
const x2 = mapValues(colors, v => v * 2);
|
|
30
|
+
const x2 = mapValues(colors, (v) => v * 2);
|
|
29
31
|
|
|
30
32
|
expect(x2.red).toBe(colors.red * 2);
|
|
31
33
|
expect(x2.blue).toBe(colors.blue * 2);
|
|
@@ -45,4 +47,4 @@ describe("mapValues() utility", () => {
|
|
|
45
47
|
const cases: cases = [false, true, true];
|
|
46
48
|
expect(cases).toBe(cases);
|
|
47
49
|
});
|
|
48
|
-
});
|
|
50
|
+
});
|
package/tests/props-spec.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
2
3
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
4
|
import {
|
|
4
5
|
KeysWithValue,
|
|
@@ -11,7 +12,7 @@ import {
|
|
|
11
12
|
NumericKeys,
|
|
12
13
|
NonStringKeys,
|
|
13
14
|
WithNumericKeys,
|
|
14
|
-
} from "
|
|
15
|
+
} from "src/types/dictionary/props";
|
|
15
16
|
|
|
16
17
|
type T0 = { foo: number; bar: number; baz: string };
|
|
17
18
|
type T1 = { foo: number; bar: number; baz?: string };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { condition, isFunction, isTrue } from "src/utility";
|
|
2
3
|
|
|
3
4
|
describe("condition() utility", () => {
|
|
4
5
|
it("basic type checks through condition abstraction", () => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
2
3
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
-
import { FunctionType } from "
|
|
4
|
-
import { type, createFnWithProps, isFunction, isObject } from "
|
|
4
|
+
import { FunctionType } from "src/types";
|
|
5
|
+
import { type, createFnWithProps, isFunction, isObject } from "src/utility";
|
|
5
6
|
|
|
6
7
|
describe("testing type() utility and some pre-made conditions", () => {
|
|
7
8
|
it("isFunction()", () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
|
|
1
|
+
import { describe, it } from "vitest";
|
|
3
2
|
|
|
3
|
+
import { literal, strArrayToDict } from "../src/utility";
|
|
4
|
+
import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
|
|
4
5
|
|
|
5
6
|
describe("strArrayToDict() utility", () => {
|
|
6
7
|
it("", () => {
|
|
@@ -29,12 +30,11 @@ describe("strArrayToDict() utility", () => {
|
|
|
29
30
|
// TODO: see if there's a way to force input to be literal
|
|
30
31
|
ExpectFalse<Equal<R4, { a: true; b: true; c: true }>>,
|
|
31
32
|
// and unfortunately it's lost all track of the keys
|
|
32
|
-
// which are involved; just knowning that they are
|
|
33
|
+
// which are involved; just knowning that they are
|
|
33
34
|
// string based keys
|
|
34
|
-
Expect<Equal<keyof R4, string
|
|
35
|
+
Expect<Equal<keyof R4, string>>
|
|
35
36
|
];
|
|
36
37
|
|
|
37
38
|
const cases: cases = [true, true, true, false, true];
|
|
38
|
-
|
|
39
39
|
});
|
|
40
|
-
});
|
|
40
|
+
});
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
1
3
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
2
|
-
import { AllCaps } from "
|
|
4
|
+
import { AllCaps } from "src/types";
|
|
3
5
|
|
|
4
6
|
describe("AllCaps<T> type utility", () => {
|
|
5
|
-
|
|
6
7
|
it("finds AllCaps where it exists", () => {
|
|
7
8
|
type T1 = AllCaps<"YUP">;
|
|
8
9
|
type T2 = AllCaps<"YUP ">;
|
|
9
10
|
type T3 = AllCaps<"YUP YUP YESSSSSSSSSSSSSS">;
|
|
10
11
|
|
|
11
|
-
type cases = [
|
|
12
|
-
Expect<Equal<T1, true>>,
|
|
13
|
-
Expect<Equal<T2, true>>,
|
|
14
|
-
Expect<Equal<T3, true>>,
|
|
15
|
-
];
|
|
12
|
+
type cases = [Expect<Equal<T1, true>>, Expect<Equal<T2, true>>, Expect<Equal<T3, true>>];
|
|
16
13
|
const c: cases = [true, true, true];
|
|
17
14
|
expect(c).toBe(c);
|
|
18
15
|
});
|
|
@@ -21,10 +18,7 @@ describe("AllCaps<T> type utility", () => {
|
|
|
21
18
|
type T1 = AllCaps<"Nope">;
|
|
22
19
|
type T2 = AllCaps<" noo nooo noooooooooooooo">;
|
|
23
20
|
|
|
24
|
-
type cases = [
|
|
25
|
-
Expect<Equal<T1, false>>,
|
|
26
|
-
Expect<Equal<T2, false>>,
|
|
27
|
-
];
|
|
21
|
+
type cases = [Expect<Equal<T1, false>>, Expect<Equal<T2, false>>];
|
|
28
22
|
const c: cases = [true, true];
|
|
29
23
|
expect(c).toBe(c);
|
|
30
24
|
});
|
|
@@ -32,11 +26,8 @@ describe("AllCaps<T> type utility", () => {
|
|
|
32
26
|
it("when passed a non literal string, returns 'unknown'", () => {
|
|
33
27
|
type T1 = AllCaps<string>;
|
|
34
28
|
|
|
35
|
-
type cases = [
|
|
36
|
-
Expect<Equal<T1, "unknown">>,
|
|
37
|
-
];
|
|
29
|
+
type cases = [Expect<Equal<T1, "unknown">>];
|
|
38
30
|
const c: cases = [true];
|
|
39
31
|
expect(c).toBe(c);
|
|
40
32
|
});
|
|
41
|
-
|
|
42
33
|
});
|