inferred-types 0.24.2 → 0.25.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/dist/index.d.ts CHANGED
@@ -165,12 +165,6 @@ declare type If<C extends boolean, T, F> = C extends T ? C | F : never;
165
165
  */
166
166
  declare type Include<T, U, L extends boolean = false> = L extends true ? T extends U ? U extends T ? T : never : never : T extends U ? T : never;
167
167
 
168
- /**
169
- * A type takes the two arguments. The first is an array of string values, the second is the value
170
- * which is being tested as it whether or not it's _included_ in the array. Result is true or false.
171
- */
172
- declare type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;
173
-
174
168
  /**
175
169
  * A "KeyedRecord" is intended to store a value without
176
170
  * losing any ability to infer type information later.
@@ -1348,6 +1342,51 @@ declare type FromDictArray<T extends [string, Record<string, unknown>][]> = Expa
1348
1342
  */
1349
1343
  declare type SecondOfEach<T extends any[][]> = T[number][1] extends T[number][number] ? T[number][1] : never;
1350
1344
 
1345
+ /**
1346
+ * **IsBooleanLiteral**
1347
+ *
1348
+ * Type utility which returns true/false if the boolean value is a _boolean literal_ versus
1349
+ * just the wider _boolean_ type.
1350
+ */
1351
+ declare type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
1352
+
1353
+ /**
1354
+ * **IsStringLiteral**
1355
+ *
1356
+ * Type utility which returns true/false if the string a _string literal_ versus
1357
+ * just the _string_ type.
1358
+ */
1359
+ declare type IsStringLiteral<T extends string> = string extends T ? false : true;
1360
+
1361
+ /**
1362
+ * **IsNumericLiteral**
1363
+ *
1364
+ * Type utility which returns true/false if the numeric value a _numeric literal_ versus
1365
+ * just the _number_ type.
1366
+ */
1367
+ declare type IsNumericLiteral<T extends number> = number extends T ? false : true;
1368
+
1369
+ /**
1370
+ * **IsLiteral**
1371
+ *
1372
+ * Type utility which returns true/false if the value passed -- a form of a
1373
+ * string, number, or boolean -- is a _literal_ value of that type (true) or
1374
+ * the more generic wide type (false).
1375
+ */
1376
+ declare type IsLiteral<T extends string | number | boolean> = [T] extends [string] ? IsStringLiteral<T> : [T] extends [boolean] ? IsBooleanLiteral<T> : [T] extends [number] ? IsNumericLiteral<T> : never;
1377
+
1378
+ /**
1379
+ * **Includes<TSource, TValue>**
1380
+ *
1381
+ * Type utility which returns `true` or `false` based on whether `TValue` is found
1382
+ * in `TSource`. Where `TSource` can be a string literal or an array of string literals.
1383
+ *
1384
+ * **Note:** if the source is a _wide_ type (aka, `string` or `string[]`) then there is
1385
+ * no way to know at design-time whether the value includes `TValue` and so it will return
1386
+ * a type of `boolean`.
1387
+ */
1388
+ declare type Includes<TSource extends string | string[], TValue extends string> = TSource extends string[] ? IsStringLiteral<TupleToUnion<TSource>> extends true ? IsLiteral<TValue> extends true ? TValue extends TupleToUnion<TSource> ? true : false : boolean : boolean : TSource extends string ? IsLiteral<TSource> extends true ? IsLiteral<TValue> extends true ? TSource extends `${string}${TValue}${string}` ? true : false : boolean : boolean : boolean;
1389
+
1351
1390
  declare function createFnWithProps<F extends Function, P extends {}>(fn: F, props: P): F & P;
1352
1391
  /**
1353
1392
  * Adds a dictionary of key/value pairs to a function.
@@ -1473,17 +1512,26 @@ declare function mapValues<N extends Narrowable, T extends Record<string, N>, V>
1473
1512
  /**
1474
1513
  * **mapTo**
1475
1514
  *
1476
- * A utility function which maps one dictionary structure `I` to another `O`; where:
1515
+ * A utility function which maps one dictionary structure `I` to another `O`; which allows
1516
+ * the transform to:
1517
+ *
1518
+ * - _split_ inputs into multiple outputs
1519
+ * - _map_ 1:1 between input and output
1520
+ * - _filter_ inputs which don't meet certain criteria (by returning `null`)
1477
1521
  *
1478
- * - `I` maps to `O[ ]` so this allows a cardinality of 0:M
1479
- * - In other words ... values from `I` can be filtered, translated 1:1 or split into multiple outputs
1480
- * - Type constrains laid out by `I` and `O` will be enforced by type system
1522
+ * This higher order function first asks for the mapping criteria:
1523
+ * ```ts
1524
+ * const mapper = mapTo<I,O>(i => i.name
1525
+ * ? [
1526
+ * { name: i.name, a: "static text", b: i.products.length }
1527
+ * ]
1528
+ * : null
1529
+ * );
1530
+ * ```
1481
1531
  *
1532
+ * and now you'll have a _mapper_ variable will be assigned as a mapping fn:
1482
1533
  * ```ts
1483
- * type I = { title: string; color: string; products: Product[] };
1484
- * type O = { title: string; count: number };
1485
- * const summarize: mapTo<I,O>()
1486
- * .map();
1534
+ * function (source: I | I[]): O[]
1487
1535
  * ```
1488
1536
  */
1489
1537
  declare const mapTo: <I extends {}, O extends {}>(cb: MapToWithFiltering<I, O>) => (source: I | I[]) => O[];
@@ -1773,4 +1821,4 @@ interface IFluentConfigurator<C> {
1773
1821
  */
1774
1822
  declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
1775
1823
 
1776
- export { AllCaps, Alpha, AlphaNumeric, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AssertExtends, Bracket, Break, CamelCase, CapitalizeWords, ClosingBracket, Condition, Configurator, Constructor, DashToSnake, DashUppercase, Dasherize, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DynamicRule, DynamicRuleSet, Email, EnumValues, ExpandRecursively, ExpectExtends, ExplicitFunction, ExtendsClause, ExtendsNarrowlyClause, Filter, FinalReturn, First, FirstKey, FirstKeyValue, FirstOfEach, FluentConfigurator, FluentFunction, FromDictArray, FunctionType, GeneralDictionary, Get, HasUppercase, IConfigurator, IFluentConfigurator, If, IfExtends, IfExtendsThen, Include, Includes, IsArray, IsBoolean, IsCapitalized, IsFalse, IsFunction, IsObject, IsString, IsTrue, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LowerAllCaps, LowerAlpha, MapTo, MapToWithFiltering, MaybeFalse, MaybeTrue, Model, Mutable, MutableProps, MutationFunction, MutationIdentity, Narrowable, NonAlpha, NonNumericKeys, NonStringKeys, Not, Numeric, NumericKeys, NumericString, ObjectType, Opaque, OpeningBracket, OptionalKeys, OptionalProps, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimplifyObject, SnakeCase, SpecialCharacters, StringDelimiter, StringKeys, StringLength, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeCondition, TypeDefinition, TypeGuard, TypeOptions, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UpperAlpha, ValueTuple, ValueTypeFunc, ValueTypes, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZipCode, and, api, arrayToKeyLookup, arrayToObject, condition, createFnWithProps, createMutationFunction, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, equals, filterDictArray, fnWithProps, greater, groupBy, idLiteral, idTypeGuard, identity, ifTypeOf, isArray, isBoolean, isFalse, isFunction, isNull, isNumber, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, less, literal, mapTo, mapValues, nameLiteral, or, randomString, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, uuid, valueTypes, withValue };
1824
+ export { AllCaps, Alpha, AlphaNumeric, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AssertExtends, Bracket, Break, CamelCase, CapitalizeWords, ClosingBracket, Condition, Configurator, Constructor, DashToSnake, DashUppercase, Dasherize, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DynamicRule, DynamicRuleSet, Email, EnumValues, ExpandRecursively, ExpectExtends, ExplicitFunction, ExtendsClause, ExtendsNarrowlyClause, Filter, FinalReturn, First, FirstKey, FirstKeyValue, FirstOfEach, FluentConfigurator, FluentFunction, FromDictArray, FunctionType, GeneralDictionary, Get, HasUppercase, IConfigurator, IFluentConfigurator, If, IfExtends, IfExtendsThen, Include, Includes, IsArray, IsBoolean, IsBooleanLiteral, IsCapitalized, IsFalse, IsFunction, IsLiteral, IsNumericLiteral, IsObject, IsString, IsStringLiteral, IsTrue, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LowerAllCaps, LowerAlpha, MapTo, MapToWithFiltering, MaybeFalse, MaybeTrue, Model, Mutable, MutableProps, MutationFunction, MutationIdentity, Narrowable, NonAlpha, NonNumericKeys, NonStringKeys, Not, Numeric, NumericKeys, NumericString, ObjectType, Opaque, OpeningBracket, OptionalKeys, OptionalProps, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimplifyObject, SnakeCase, SpecialCharacters, StringDelimiter, StringKeys, StringLength, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeCondition, TypeDefinition, TypeGuard, TypeOptions, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UpperAlpha, ValueTuple, ValueTypeFunc, ValueTypes, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZipCode, and, api, arrayToKeyLookup, arrayToObject, condition, createFnWithProps, createMutationFunction, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, equals, filterDictArray, fnWithProps, greater, groupBy, idLiteral, idTypeGuard, identity, ifTypeOf, isArray, isBoolean, isFalse, isFunction, isNull, isNumber, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, less, literal, mapTo, mapValues, nameLiteral, or, randomString, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, uuid, valueTypes, withValue };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inferred-types",
3
- "version": "0.24.2",
3
+ "version": "0.25.0",
4
4
  "description": "Functions which provide useful type inference on TS projects",
5
5
  "license": "MIT",
6
6
  "author": "Ken Snyder<ken@ken.net>",
@@ -46,6 +46,7 @@
46
46
  "eslint-plugin-prettier": "^4.2.1",
47
47
  "eslint-plugin-promise": "^6.1.1",
48
48
  "npm-run-all": "~4.1.5",
49
+ "pathe": "^0.3.9",
49
50
  "prettier": "~2.7.1",
50
51
  "rimraf": "^3.0.2",
51
52
  "sharp": "^0.31.1",
@@ -0,0 +1,34 @@
1
+ import { TupleToUnion } from "../type-conversion";
2
+ import { IsLiteral } from "./IsLiteral";
3
+ import { IsStringLiteral } from "./IsStringLiteral";
4
+
5
+ /**
6
+ * **Includes<TSource, TValue>**
7
+ *
8
+ * Type utility which returns `true` or `false` based on whether `TValue` is found
9
+ * in `TSource`. Where `TSource` can be a string literal or an array of string literals.
10
+ *
11
+ * **Note:** if the source is a _wide_ type (aka, `string` or `string[]`) then there is
12
+ * no way to know at design-time whether the value includes `TValue` and so it will return
13
+ * a type of `boolean`.
14
+ */
15
+ export type Includes<
16
+ TSource extends string | string[],
17
+ TValue extends string
18
+ > = TSource extends string[]
19
+ ? IsStringLiteral<TupleToUnion<TSource>> extends true
20
+ ? IsLiteral<TValue> extends true
21
+ ? TValue extends TupleToUnion<TSource>
22
+ ? true
23
+ : false
24
+ : boolean
25
+ : boolean
26
+ : TSource extends string
27
+ ? IsLiteral<TSource> extends true
28
+ ? IsLiteral<TValue> extends true
29
+ ? TSource extends `${string}${TValue}${string}`
30
+ ? true
31
+ : false
32
+ : boolean
33
+ : boolean
34
+ : boolean;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * **IsBooleanLiteral**
3
+ *
4
+ * Type utility which returns true/false if the boolean value is a _boolean literal_ versus
5
+ * just the wider _boolean_ type.
6
+ */
7
+ export type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
@@ -0,0 +1,20 @@
1
+ import { IsBooleanLiteral } from "./IsBooleanLiteral";
2
+ import { IsStringLiteral } from "./IsStringLiteral";
3
+ import { IsNumericLiteral } from "./IsNumericLiteral";
4
+
5
+ // [note on handling of boolean](https://stackoverflow.com/questions/74213646/detecting-type-literals-works-in-isolation-but-not-when-combined-with-other-lite/74213713#74213713)
6
+
7
+ /**
8
+ * **IsLiteral**
9
+ *
10
+ * Type utility which returns true/false if the value passed -- a form of a
11
+ * string, number, or boolean -- is a _literal_ value of that type (true) or
12
+ * the more generic wide type (false).
13
+ */
14
+ export type IsLiteral<T extends string | number | boolean> = [T] extends [string]
15
+ ? IsStringLiteral<T>
16
+ : [T] extends [boolean]
17
+ ? IsBooleanLiteral<T>
18
+ : [T] extends [number]
19
+ ? IsNumericLiteral<T>
20
+ : never;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * **IsNumericLiteral**
3
+ *
4
+ * Type utility which returns true/false if the numeric value a _numeric literal_ versus
5
+ * just the _number_ type.
6
+ */
7
+ export type IsNumericLiteral<T extends number> = number extends T ? false : true;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * **IsStringLiteral**
3
+ *
4
+ * Type utility which returns true/false if the string a _string literal_ versus
5
+ * just the _string_ type.
6
+ */
7
+ export type IsStringLiteral<T extends string> = string extends T ? false : true;
@@ -0,0 +1,5 @@
1
+ export * from "./Includes";
2
+ export * from "./IsBooleanLiteral";
3
+ export * from "./IsNumericLiteral";
4
+ export * from "./IsStringLiteral";
5
+ export * from "./IsLiteral";
@@ -12,7 +12,6 @@ export * from "./First";
12
12
  export * from "./FunctionType";
13
13
  export * from "./If";
14
14
  export * from "./Include";
15
- export * from "./Includes";
16
15
  export * from "./KeyedRecord";
17
16
  export * from "./Keys";
18
17
  export * from "./Length";
@@ -41,6 +40,7 @@ export * from "./lists/index";
41
40
  export * from "./string-literals/index";
42
41
  export * from "./tuples/index";
43
42
  export * from "./type-conversion/index";
43
+ export * from "./TypeInfo/index";
44
44
 
45
45
  // #endregion auto-indexed files
46
46
 
@@ -3,17 +3,26 @@ import { MapToWithFiltering } from "src/types/dictionary";
3
3
  /**
4
4
  * **mapTo**
5
5
  *
6
- * A utility function which maps one dictionary structure `I` to another `O`; where:
6
+ * A utility function which maps one dictionary structure `I` to another `O`; which allows
7
+ * the transform to:
7
8
  *
8
- * - `I` maps to `O[ ]` so this allows a cardinality of 0:M
9
- * - In other words ... values from `I` can be filtered, translated 1:1 or split into multiple outputs
10
- * - Type constrains laid out by `I` and `O` will be enforced by type system
9
+ * - _split_ inputs into multiple outputs
10
+ * - _map_ 1:1 between input and output
11
+ * - _filter_ inputs which don't meet certain criteria (by returning `null`)
11
12
  *
13
+ * This higher order function first asks for the mapping criteria:
12
14
  * ```ts
13
- * type I = { title: string; color: string; products: Product[] };
14
- * type O = { title: string; count: number };
15
- * const summarize: mapTo<I,O>()
16
- * .map();
15
+ * const mapper = mapTo<I,O>(i => i.name
16
+ * ? [
17
+ * { name: i.name, a: "static text", b: i.products.length }
18
+ * ]
19
+ * : null
20
+ * );
21
+ * ```
22
+ *
23
+ * and now you'll have a _mapper_ variable will be assigned as a mapping fn:
24
+ * ```ts
25
+ * function (source: I | I[]): O[]
17
26
  * ```
18
27
  */
19
28
  export const mapTo =
@@ -1,15 +1,36 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
3
  import type { Includes } from "../src/types";
4
- import type { ExpectTrue, ExpectFalse } from "@type-challenges/utils";
4
+ import type { Equal, Expect } from "@type-challenges/utils";
5
5
 
6
6
  describe("Includes type check", () => {
7
- it("Includes tests whether string is contained within the string array", () => {
7
+ it("Includes works on a string source", () => {
8
+ type T = Includes<"Hello World", "Hello">;
9
+ type F = Includes<"Hello World", "nada">;
10
+ type U = Includes<string, "who cares">;
11
+ type N = Includes<"Hello World", string>;
8
12
  type cases = [
9
- ExpectTrue<Includes<["foo", "bar", "baz"], "foo">>,
10
- ExpectFalse<Includes<["foo", "bar", "baz"], "nada">>
13
+ Expect<Equal<T, true>>, //
14
+ Expect<Equal<F, false>>,
15
+ Expect<Equal<U, boolean>>,
16
+ Expect<Equal<N, boolean>>
11
17
  ];
12
- const typeTests: cases = [true, false];
18
+ const typeTests: cases = [true, true, true, true];
19
+ expect(typeTests).toBe(typeTests);
20
+ });
21
+
22
+ it("Includes works on a string[] source", () => {
23
+ type T = Includes<["Hello", "World"], "Hello">;
24
+ type F = Includes<["Hello", "World"], "nada">;
25
+ type U = Includes<string[], "who cares">;
26
+ type N = Includes<["Hello", "World"], string>;
27
+ type cases = [
28
+ Expect<Equal<T, true>>, //
29
+ Expect<Equal<F, false>>,
30
+ Expect<Equal<U, boolean>>,
31
+ Expect<Equal<N, boolean>>
32
+ ];
33
+ const typeTests: cases = [true, true, true, true];
13
34
  expect(typeTests).toBe(typeTests);
14
35
  });
15
36
  });
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { Equal, Expect } from "@type-challenges/utils";
3
+ import { IsBooleanLiteral, IsLiteral } from "src/types";
4
+
5
+ describe("IsLiteral<T> type utility", () => {
6
+ it("string values", () => {
7
+ const s = "hi" as string;
8
+ const sl = "hi" as const;
9
+
10
+ type cases = [
11
+ Expect<Equal<IsLiteral<typeof s>, false>>,
12
+ Expect<Equal<IsLiteral<typeof sl>, true>>
13
+ ];
14
+ const cases: cases = [true, true];
15
+ expect(typeof s).toBe("string");
16
+ expect(typeof sl).toBe("string");
17
+ });
18
+
19
+ it("numeric values", () => {
20
+ const v = 42 as number;
21
+ const vl = 42 as const;
22
+
23
+ type cases = [
24
+ Expect<Equal<IsLiteral<typeof v>, false>>,
25
+ Expect<Equal<IsLiteral<typeof vl>, true>>
26
+ ];
27
+ const cases: cases = [true, true];
28
+
29
+ expect(typeof v).toBe("number");
30
+ expect(typeof vl).toBe("number");
31
+ });
32
+
33
+ it("boolean values", () => {
34
+ const v = true as boolean;
35
+ const vl = false as const;
36
+
37
+ type cases = [
38
+ // wide
39
+ Expect<Equal<IsBooleanLiteral<typeof v>, false>>,
40
+ Expect<Equal<IsLiteral<typeof v>, false>>,
41
+ // literal
42
+ Expect<Equal<IsBooleanLiteral<typeof vl>, true>>,
43
+ Expect<Equal<IsLiteral<typeof vl>, true>>
44
+ ];
45
+ const cases: cases = [true, true, true, true];
46
+ expect(typeof v).toBe("boolean");
47
+ expect(typeof vl).toBe("boolean");
48
+ });
49
+ });
package/tsconfig.json CHANGED
@@ -16,6 +16,14 @@
16
16
  "lib": [
17
17
  "ES2020"
18
18
  ],
19
+ "paths": {
20
+ "src/*": [
21
+ "src/*"
22
+ ],
23
+ "test/*": [
24
+ "test/*"
25
+ ]
26
+ },
19
27
  "baseUrl": ".",
20
28
  "declaration": true,
21
29
  "outDir": "dist",
package/vitest.config.ts CHANGED
@@ -1,8 +1,15 @@
1
1
  /// <reference types="vitest" />
2
2
  import { defineConfig } from "vite";
3
+ import { resolve } from "pathe";
3
4
 
4
5
  // used for testing, library code uses TSUP to build exports
5
6
  export default defineConfig({
7
+ resolve: {
8
+ alias: {
9
+ src: resolve(__dirname, "./src"),
10
+ test: resolve(__dirname, "./test"),
11
+ },
12
+ },
6
13
  test: {
7
14
  dir: "tests",
8
15
  api: {
@@ -1,5 +0,0 @@
1
- /**
2
- * A type takes the two arguments. The first is an array of string values, the second is the value
3
- * which is being tested as it whether or not it's _included_ in the array. Result is true or false.
4
- */
5
- export type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;