inferred-types 0.33.1 → 0.33.3
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 +1209 -1152
- 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 -6
- 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 +4 -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
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IfStringLiteral } from "src/types/type-checks";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **EndsWith**<T,U>
|
|
5
|
+
*
|
|
6
|
+
* A type utility which checks whether `T` _ends with_ the string literal `U`.
|
|
7
|
+
*
|
|
8
|
+
* If both `T` and `U` are string literals then the type system will resolve
|
|
9
|
+
* to a literal `true` or `false` but if either is not a literal that it will
|
|
10
|
+
* just resolve to `boolean` as the value can not be known at design time..
|
|
11
|
+
*/
|
|
12
|
+
export type EndsWith<T extends unknown, U extends unknown> = T extends string
|
|
13
|
+
? U extends string
|
|
14
|
+
? T extends `${string}${U}`
|
|
15
|
+
? IfStringLiteral<
|
|
16
|
+
T, //
|
|
17
|
+
IfStringLiteral<U, true, boolean>,
|
|
18
|
+
boolean
|
|
19
|
+
>
|
|
20
|
+
: IfStringLiteral<T, false, boolean>
|
|
21
|
+
: false
|
|
22
|
+
: false;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -4,15 +4,11 @@
|
|
|
4
4
|
* Type utility which returns true/false if the string a _string literal_ versus
|
|
5
5
|
* just the _string_ type.
|
|
6
6
|
*/
|
|
7
|
-
export type IsStringLiteral<T> = T extends string
|
|
8
|
-
? string extends T ? false : true
|
|
9
|
-
: false;
|
|
7
|
+
export type IsStringLiteral<T> = [T] extends [string] ? (string extends T ? false : true) : false;
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* **IfStringLiteral**
|
|
13
11
|
*
|
|
14
12
|
* Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
|
|
15
13
|
*/
|
|
16
|
-
export type IfStringLiteral<T
|
|
17
|
-
? IF
|
|
18
|
-
: ELSE;
|
|
14
|
+
export type IfStringLiteral<T, IF, ELSE> = [IsStringLiteral<T>] extends [true] ? IF : ELSE;
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { IfStringLiteral } from "src/types/type-checks";
|
|
2
|
+
import { Narrowable } from "../Narrowable";
|
|
3
|
+
/**
|
|
4
|
+
* **StartsWith**<TValue, TStartsWith>
|
|
5
|
+
*
|
|
6
|
+
* A type utility which checks whether `T` _starts with_ the string literal `U`.
|
|
7
|
+
*
|
|
8
|
+
* If both `T` and `U` are string literals then the type system will resolve
|
|
9
|
+
* to a literal `true` or `false` but if either is not a literal that it will
|
|
10
|
+
* just resolve to `boolean` as the value can not be known at design time..
|
|
11
|
+
*/
|
|
12
|
+
export type StartsWith<TValue extends unknown, TStartsWith extends unknown> = TValue extends string
|
|
13
|
+
? TStartsWith extends string
|
|
14
|
+
? TValue extends `${TStartsWith}${string}`
|
|
15
|
+
? IfStringLiteral<
|
|
16
|
+
TValue, //
|
|
17
|
+
IfStringLiteral<TStartsWith, true, boolean>,
|
|
18
|
+
boolean
|
|
19
|
+
>
|
|
20
|
+
: IfStringLiteral<TValue, false, boolean>
|
|
21
|
+
: false
|
|
22
|
+
: false;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* **IfStartsWith**<TValue, TStartsWith, IF, ELSE, MAYBE>
|
|
26
|
+
*
|
|
27
|
+
* Type utility which converts type to `IF` type _if_ TValue _starts with_ `TStartsWith` but
|
|
28
|
+
* otherwise converts type to `ELSE`.
|
|
29
|
+
*
|
|
30
|
+
* Note, that there is also an optional `MAYBE` type
|
|
31
|
+
* which can be stated for cases where TValue or TStartsWith _might_ be the wider `string`
|
|
32
|
+
* type and therefore the type is unknown at design time.
|
|
33
|
+
*/
|
|
34
|
+
export type IfStartsWith<
|
|
35
|
+
TValue extends unknown,
|
|
36
|
+
TStartsWith extends unknown,
|
|
37
|
+
IF extends Narrowable,
|
|
38
|
+
ELSE extends Narrowable
|
|
39
|
+
> = StartsWith<TValue, TStartsWith> extends true
|
|
40
|
+
? IF
|
|
41
|
+
: StartsWith<TValue, TStartsWith> extends false
|
|
42
|
+
? ELSE
|
|
43
|
+
: IF | ELSE;
|
|
@@ -4,6 +4,9 @@ export * from "./IsNumericLiteral";
|
|
|
4
4
|
export * from "./IsScalar";
|
|
5
5
|
export * from "./IsStringLiteral";
|
|
6
6
|
export * from "./IsLiteral";
|
|
7
|
+
export * from "./IsUndefined";
|
|
7
8
|
export * from "./Extends";
|
|
8
9
|
export * from "./TypeDefault";
|
|
9
|
-
export * from "./
|
|
10
|
+
export * from "./object";
|
|
11
|
+
export * from "./StartsWith";
|
|
12
|
+
export * from "./EndsWith";
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Narrowable } from "src/types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **IsString**
|
|
5
|
+
*
|
|
6
|
+
* Type utility which returns true/false based on whether `T` is a
|
|
7
|
+
* string (wide or narrow).
|
|
8
|
+
*/
|
|
9
|
+
export type IsString<T> = T extends string ? true : false;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* **IfString**
|
|
13
|
+
*
|
|
14
|
+
* Type utility which determines if `T` is a _string_ (wide or narrow) and
|
|
15
|
+
* returns `IF` type if it is, otherwise returns the type `ELSE`.
|
|
16
|
+
*/
|
|
17
|
+
export type IfString<
|
|
18
|
+
T extends Narrowable, //
|
|
19
|
+
IF extends Narrowable,
|
|
20
|
+
ELSE extends Narrowable
|
|
21
|
+
> = IsString<T> extends true ? IF : ELSE;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Mutable } from "../Mutable";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Converts a Tuple type into a _union_ of the tuple elements
|
|
5
3
|
* ```ts
|
|
@@ -8,4 +6,4 @@ import { Mutable } from "../Mutable";
|
|
|
8
6
|
* type U = TupleToUnion<typeof arr>;
|
|
9
7
|
* ```
|
|
10
8
|
*/
|
|
11
|
-
export type TupleToUnion<T> =
|
|
9
|
+
export type TupleToUnion<T> = T extends readonly any[] ? T[number] : never;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
4
|
-
import { arrayToKeyLookup } from "../src/
|
|
4
|
+
import { arrayToKeyLookup } from "../src/runtime";
|
|
5
5
|
|
|
6
6
|
describe("arrayToKeyLookup()", () => {
|
|
7
7
|
it("simple string array is converted", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
// import type { Equal, Expect } from "@type-challenges/utils";
|
|
3
|
-
import { and, filter } from "src/
|
|
3
|
+
import { and, filter } from "src/runtime";
|
|
4
4
|
|
|
5
5
|
describe("boolean logic", () => {
|
|
6
6
|
it("AND operation", () => {
|
package/tests/defineType-spec.ts
CHANGED
|
@@ -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 { ExpectExtends } from "../src/types";
|
|
5
|
-
import { defineType } from "../src/
|
|
5
|
+
import { defineType } from "../src/runtime";
|
|
6
6
|
|
|
7
7
|
describe("inferredType() utility", () => {
|
|
8
8
|
it("only specify a wide type", () => {
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
4
4
|
import { Get } from "src/types";
|
|
5
|
-
import { defineType } from "src/
|
|
5
|
+
import { defineType } from "src/runtime";
|
|
6
6
|
|
|
7
7
|
describe("Get<T, K> type utility", () => {
|
|
8
8
|
it("Get<T,K> works with literals and wide types", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it } from "vitest";
|
|
2
2
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
3
|
-
import { TypeDefault } from "src/types/
|
|
4
|
-
import { literal } from "src/
|
|
3
|
+
import { TypeDefault } from "src/types/type-checks/TypeDefault";
|
|
4
|
+
import { literal } from "src/runtime/literals";
|
|
5
5
|
|
|
6
6
|
describe("TypeDefault<T,D>", () => {
|
|
7
7
|
it("T/D as dictionary", () => {
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
DEFAULT_MANY_TO_ONE_MAPPING,
|
|
17
17
|
DEFAULT_ONE_TO_MANY_MAPPING,
|
|
18
18
|
mapTo,
|
|
19
|
-
} from "src/
|
|
19
|
+
} from "src/runtime/dictionary/mapTo";
|
|
20
20
|
|
|
21
21
|
type I = { title: string; color: string; products: string[] };
|
|
22
22
|
const i: I = { title: "Test", color: "green", products: ["foo", "bar", "baz"] };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { dictionaryTransform, ExplicitFunction } from "../src/
|
|
2
|
+
import { dictionaryTransform, ExplicitFunction } from "../src/runtime";
|
|
3
3
|
import { Expect, Equal, NotEqual, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
|
|
4
4
|
import { ToFluent, Transformer } from "../src/types";
|
|
5
5
|
|
package/tests/ifTypeOf-spec.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
4
4
|
import { Expect, Equal } from "@type-challenges/utils";
|
|
5
|
-
import {
|
|
5
|
+
import { defineType, literal } from "../src/runtime";
|
|
6
|
+
import { ifTypeOf } from "src/runtime/type-checks/ifTypeOf";
|
|
6
7
|
|
|
7
8
|
describe("ifTypeOf() utility", () => {
|
|
8
9
|
it("base validation with extends() returns true/false", () => {
|
|
@@ -142,7 +143,7 @@ describe("ifTypeOf() utility", () => {
|
|
|
142
143
|
// literal types and broader types; this is not hard to express with types
|
|
143
144
|
// but it makes our approach much more awkward and the API much more cumbersome
|
|
144
145
|
|
|
145
|
-
// here we see a type that represents this
|
|
146
|
+
// here we see a type that represents this challenge but how it fails with
|
|
146
147
|
// with the runtime
|
|
147
148
|
|
|
148
149
|
const literal = { foo: 1 } as const;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { Equal, Expect, NotEqual } from "@type-challenges/utils";
|
|
4
|
-
import { dictToKv, kvToDict } from "src/
|
|
4
|
+
import { dictToKv, kvToDict } from "src/runtime/dictionary";
|
|
5
5
|
import { DictFromKv } from "src/types/kv";
|
|
6
|
-
import { keys } from "src/
|
|
6
|
+
import { keys } from "src/runtime";
|
|
7
7
|
|
|
8
8
|
describe("dictToKv()", () => {
|
|
9
9
|
it.skip("basic structure is correct when forcing to Tuple structure", () => {
|
package/tests/kv/entries-spec.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
3
|
import type { Expect, NotEqual, Equal, ExpectExtends } from "@type-challenges/utils";
|
|
4
|
-
import { entries } from "src/
|
|
4
|
+
import { entries } from "src/runtime";
|
|
5
5
|
|
|
6
6
|
describe("entries() => ", () => {
|
|
7
7
|
it("literal types are retained", () => {
|
package/tests/kv/keys.spec.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import { Keys } from "src/types/Keys";
|
|
4
4
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
5
|
-
import { defineType, keys } from "src/
|
|
5
|
+
import { defineType, keys } from "src/runtime";
|
|
6
6
|
|
|
7
7
|
describe("Keys<T>", () => {
|
|
8
8
|
it("Keys<T> is shorthand for keyof T", () => {
|
package/tests/kv/kv-spec.ts
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it } from "vitest";
|
|
2
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
+
import { AfterFirst, First } from "src/types/lists";
|
|
4
|
+
|
|
5
|
+
describe("First<T>, AfterFirst<T>", () => {
|
|
6
|
+
it("First<T> with literals", () => {
|
|
7
|
+
const arr = ["one", "two", 42] as const;
|
|
8
|
+
type F = First<typeof arr>;
|
|
9
|
+
type cases = [Expect<Equal<F, "one">>];
|
|
10
|
+
const cases: cases = [true];
|
|
11
|
+
});
|
|
12
|
+
it("First<T> with wide types but literal array", () => {
|
|
13
|
+
const arr = ["one" as string, "two", 42] as const;
|
|
14
|
+
type F = First<typeof arr>;
|
|
15
|
+
type cases = [Expect<Equal<F, string>>];
|
|
16
|
+
const cases: cases = [true];
|
|
17
|
+
});
|
|
18
|
+
it("First<T> with a non const array", () => {
|
|
19
|
+
const arr = ["one", "two", 42];
|
|
20
|
+
type F = First<typeof arr>;
|
|
21
|
+
type cases = [Expect<Equal<F, string | number>>];
|
|
22
|
+
const cases: cases = [true];
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("AfterFirst<T> with literals", () => {
|
|
26
|
+
const arr = ["one", "two", 42] as const;
|
|
27
|
+
type AF = AfterFirst<typeof arr>;
|
|
28
|
+
type cases = [Expect<Equal<AF, ["two", 42]>>];
|
|
29
|
+
const cases: cases = [true];
|
|
30
|
+
});
|
|
31
|
+
it("AfterFirst<T> with wide types but literal array", () => {
|
|
32
|
+
const arr = ["one", "two" as string, 42] as const;
|
|
33
|
+
type AF = AfterFirst<typeof arr>;
|
|
34
|
+
type cases = [Expect<Equal<AF, [string, 42]>>];
|
|
35
|
+
const cases: cases = [true];
|
|
36
|
+
});
|
|
37
|
+
it("AfterFirst<T> with a non const array", () => {
|
|
38
|
+
const arr = ["one", "two", 42];
|
|
39
|
+
type AF = AfterFirst<typeof arr>;
|
|
40
|
+
type cases = [Expect<Equal<AF, (string | number)[]>>];
|
|
41
|
+
const cases: cases = [true];
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it } from "vitest";
|
|
2
|
+
import type { Expect, Equal } from "@type-challenges/utils";
|
|
3
|
+
import { Split } from "src/types/lists";
|
|
4
|
+
|
|
5
|
+
describe("Split<T, SEP>", () => {
|
|
6
|
+
it("Split<T, SEP> with string literals", () => {
|
|
7
|
+
const str = "hello world, nice to meet you" as const;
|
|
8
|
+
type S = Split<typeof str, " ">;
|
|
9
|
+
|
|
10
|
+
type cases = [Expect<Equal<S, ["hello", "world,", "nice", "to", "meet", "you"]>>];
|
|
11
|
+
const cases: cases = [true];
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("Split<T, SEP> where string and separator are same", () => {
|
|
15
|
+
const str = "hello world, 42 nice to meet you" as const;
|
|
16
|
+
type S = Split<typeof str, typeof str>;
|
|
17
|
+
|
|
18
|
+
type cases = [Expect<Equal<S, []>>];
|
|
19
|
+
const cases: cases = [true];
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("Split<T, SEP> string is wide type", () => {
|
|
23
|
+
const str = "hello world, 42 nice to meet you" as string;
|
|
24
|
+
type S = Split<typeof str, ",">;
|
|
25
|
+
|
|
26
|
+
type cases = [Expect<Equal<S, string[]>>];
|
|
27
|
+
const cases: cases = [true];
|
|
28
|
+
});
|
|
29
|
+
});
|
package/tests/literal-spec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { idLiteral, literal } from "../src/
|
|
3
|
+
import { idLiteral, literal } from "../src/runtime";
|
|
4
4
|
import { Equal, NotEqual, Expect, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
|
|
5
5
|
|
|
6
6
|
describe("literal enforcement", () => {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { Equal, Expect } from "@type-challenges/utils";
|
|
3
|
+
import { Box, box, BoxedFnParams, BoxValue } from "src/runtime";
|
|
4
|
+
import { First } from "src/types/lists/First";
|
|
5
|
+
|
|
6
|
+
// [Instantiation Expressions](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#instantiation-expressions)
|
|
7
|
+
|
|
8
|
+
describe("boxing / unboxing", () => {
|
|
9
|
+
// it("NarrowBox<B,N> utility", () => {
|
|
10
|
+
// const fn = <T extends string>(i: T) => `Hello ${i}` as const;
|
|
11
|
+
// const b = box(fn);
|
|
12
|
+
// const b2 = b.narrow<["foo" | "bar"]>();
|
|
13
|
+
// const b3 = b2("foo");
|
|
14
|
+
|
|
15
|
+
// type B = typeof b;
|
|
16
|
+
// });
|
|
17
|
+
|
|
18
|
+
it("box a function with generic", () => {
|
|
19
|
+
const fn = <T extends string>(i: T) => `Hello ${i}` as const;
|
|
20
|
+
const b = box(fn);
|
|
21
|
+
const ub = b.unbox();
|
|
22
|
+
type UB = typeof ub;
|
|
23
|
+
const unboxedFn = b.unbox()("foo");
|
|
24
|
+
const unboxedFn2 = b.unbox()("foo" as string);
|
|
25
|
+
type UBF = typeof unboxedFn;
|
|
26
|
+
type UBF2 = typeof unboxedFn2;
|
|
27
|
+
|
|
28
|
+
const bn = box(42);
|
|
29
|
+
type BN = typeof bn;
|
|
30
|
+
const rn = bn.unbox();
|
|
31
|
+
type RN = typeof rn;
|
|
32
|
+
const rn2 = bn.value;
|
|
33
|
+
type RN2 = typeof rn2;
|
|
34
|
+
|
|
35
|
+
type Hybrid = 42 | 56 | typeof fn;
|
|
36
|
+
const h = box(42 as Hybrid);
|
|
37
|
+
type H = typeof h;
|
|
38
|
+
type HV = H["value"];
|
|
39
|
+
|
|
40
|
+
// runtime
|
|
41
|
+
expect(typeof b).toBe("object");
|
|
42
|
+
expect(typeof ub).toBe("function");
|
|
43
|
+
expect(unboxedFn).toBe("Hello foo");
|
|
44
|
+
|
|
45
|
+
expect(rn).toBe(42);
|
|
46
|
+
expect(rn2).toBe(42);
|
|
47
|
+
|
|
48
|
+
// type tests
|
|
49
|
+
type B = typeof b;
|
|
50
|
+
type BV = BoxValue<B>;
|
|
51
|
+
type BF = First<BoxedFnParams<B>>;
|
|
52
|
+
|
|
53
|
+
type cases = [
|
|
54
|
+
// FUNCTIONS
|
|
55
|
+
Expect<Equal<B, Box<typeof fn>>>,
|
|
56
|
+
Expect<Equal<BV, typeof fn>>, //
|
|
57
|
+
Expect<Equal<BF, string>>,
|
|
58
|
+
/** unboxing fn results in same fn including generics */
|
|
59
|
+
Expect<Equal<UB, typeof fn>>,
|
|
60
|
+
/** generic for fn provides strong literal type after unboxing */
|
|
61
|
+
Expect<Equal<UBF, "Hello foo">>,
|
|
62
|
+
/** generic still provides some strong typing when a wide type is passed in */
|
|
63
|
+
Expect<Equal<UBF2, `Hello ${string}`>>,
|
|
64
|
+
|
|
65
|
+
// NUMBER BOXes
|
|
66
|
+
Expect<Equal<BN, Box<42>>>,
|
|
67
|
+
/** unboxing preserves numeric literal */
|
|
68
|
+
Expect<Equal<RN, 42>>,
|
|
69
|
+
/** can pick off the value prop for same type */
|
|
70
|
+
Expect<Equal<RN2, 42>>,
|
|
71
|
+
|
|
72
|
+
// HYBRID
|
|
73
|
+
Expect<Equal<HV, Hybrid>>
|
|
74
|
+
];
|
|
75
|
+
const cases: cases = [true, true, true, true, true, true, true, true, true, true];
|
|
76
|
+
});
|
|
77
|
+
});
|
|
File without changes
|
package/tests/mapValues-spec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { mapValues, literal } from "../src/
|
|
3
|
+
import { mapValues, literal } from "../src/runtime";
|
|
4
4
|
import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
|
|
5
5
|
|
|
6
6
|
describe("mapValues() utility", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { condition, isFunction, isTrue } from "src/
|
|
2
|
+
import { condition, isFunction, isTrue } from "src/runtime";
|
|
3
3
|
|
|
4
4
|
describe("condition() utility", () => {
|
|
5
5
|
it("basic type checks through condition abstraction", () => {
|