inferred-types 0.24.1 → 0.24.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/dist/index.d.ts CHANGED
@@ -585,23 +585,26 @@ O extends (...args: any[]) => any = (...args: any[]) => any> = SimplifyObject<{
585
585
  declare type Get<T, K> = K extends `${infer FK}.${infer L}` ? FK extends keyof T ? Get<T[FK], L> : never : K extends keyof T ? T[K] : never;
586
586
 
587
587
  /**
588
- * Maps from one type `I` to another `O`, where:
588
+ * **MapTo**
589
589
  *
590
- * - a **null** value indicates that there is no valid mapping for the given input
591
- * - you can either return a 1:1 or 1:M output as `O` or `O[]` when there is a mapping
590
+ * Maps from one type `I` to another `O[]`
592
591
  *
593
- * This type utility will ensure both `I` and `O` are honoured but if the runtime only
594
- * uses the type utility it's worth bearing in mind that while _typing_ will be as expected
595
- * the output parameter can assume properties that in fact do not reside
596
- *
597
- * ```ts
598
- * const mapper: ModelMapper<{title: string}, {title: string, kind: string}> = i => {
599
- * title: i.title,
600
- * kind: "markdown"
601
- * }
602
- * ```
592
+ * **Note:** because the output is an array you can easily support `1:1` and `1:M` mappings
593
+ * but not a filtering operation (e.g., `1:0`); if you need this then use `MapToWithFiltering`
594
+ * instead.
603
595
  */
604
596
  declare type MapTo<I extends {}, O extends {}> = (i: I) => O[];
597
+ /**
598
+ * **MapToWithFiltering**
599
+ *
600
+ * Maps from one type `I` to another `(O | null)[]`
601
+ *
602
+ * **Note:** because the output is an array you can easily support `1:1` and `1:M` mappings
603
+ * and the allowance of the conversion to result in a `null` value also means that filter
604
+ * out an input value entirely is possible. If you don't need _filtering_ then use the
605
+ * `MapTo` type instead.
606
+ */
607
+ declare type MapToWithFiltering<I extends {}, O extends {}> = (i: I) => O[] | null;
605
608
 
606
609
  /**
607
610
  * Given a dictionary of type `<T>`, this utility function will
@@ -1470,20 +1473,29 @@ declare function mapValues<N extends Narrowable, T extends Record<string, N>, V>
1470
1473
  /**
1471
1474
  * **mapTo**
1472
1475
  *
1473
- * A utility function which maps one dictionary structure `I` to another `O`; where:
1476
+ * A utility function which maps one dictionary structure `I` to another `O`; which allows
1477
+ * the transform to:
1478
+ *
1479
+ * - _split_ inputs into multiple outputs
1480
+ * - _map_ 1:1 between input and output
1481
+ * - _filter_ inputs which don't meet certain criteria (by returning `null`)
1474
1482
  *
1475
- * - `I` maps to `O[ ]` so this allows a cardinality of 0:M
1476
- * - In other words ... values from `I` can be filtered, translated 1:1 or split into multiple outputs
1477
- * - Type constrains laid out by `I` and `O` will be enforced by type system
1483
+ * This higher order function first asks for the mapping criteria:
1484
+ * ```ts
1485
+ * const mapper = mapTo<I,O>(i => i.name
1486
+ * ? [
1487
+ * { name: i.name, a: "static text", b: i.products.length }
1488
+ * ]
1489
+ * : null
1490
+ * );
1491
+ * ```
1478
1492
  *
1493
+ * and now you'll have a _mapper_ variable will be assigned as a mapping fn:
1479
1494
  * ```ts
1480
- * type I = { title: string; color: string; products: Product[] };
1481
- * type O = { title: string; count: number };
1482
- * const summarize: mapTo<I,O>()
1483
- * .map();
1495
+ * function (source: I | I[]): O[]
1484
1496
  * ```
1485
1497
  */
1486
- declare const mapTo: <I extends {}, O extends {}>(cb: MapTo<I, O>) => (source: I) => O[];
1498
+ declare const mapTo: <I extends {}, O extends {}>(cb: MapToWithFiltering<I, O>) => (source: I | I[]) => O[];
1487
1499
 
1488
1500
  /**
1489
1501
  * converts an array of strings `["a", "b", "c"]` into a more type friendly
@@ -1770,4 +1782,4 @@ interface IFluentConfigurator<C> {
1770
1782
  */
1771
1783
  declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
1772
1784
 
1773
- 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, 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 };
1785
+ 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 };
package/dist/index.js CHANGED
@@ -262,7 +262,14 @@ function mapValues(obj, valueMapper) {
262
262
  }
263
263
 
264
264
  // src/utility/dictionary/mapTo.ts
265
- var mapTo = (cb) => (source) => cb(source);
265
+ var mapTo = (cb) => (source) => {
266
+ if (Array.isArray(source)) {
267
+ return source.flatMap((i) => cb(i)).filter((i) => i !== null);
268
+ } else {
269
+ const result = cb(source);
270
+ return result ? result : [];
271
+ }
272
+ };
266
273
 
267
274
  // src/utility/dictionary/strArrayToDict.ts
268
275
  function strArrayToDict(...strings) {
package/dist/index.mjs CHANGED
@@ -179,7 +179,14 @@ function mapValues(obj, valueMapper) {
179
179
  }
180
180
 
181
181
  // src/utility/dictionary/mapTo.ts
182
- var mapTo = (cb) => (source) => cb(source);
182
+ var mapTo = (cb) => (source) => {
183
+ if (Array.isArray(source)) {
184
+ return source.flatMap((i) => cb(i)).filter((i) => i !== null);
185
+ } else {
186
+ const result = cb(source);
187
+ return result ? result : [];
188
+ }
189
+ };
183
190
 
184
191
  // src/utility/dictionary/strArrayToDict.ts
185
192
  function strArrayToDict(...strings) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inferred-types",
3
- "version": "0.24.1",
3
+ "version": "0.24.3",
4
4
  "description": "Functions which provide useful type inference on TS projects",
5
5
  "license": "MIT",
6
6
  "author": "Ken Snyder<ken@ken.net>",
@@ -32,19 +32,19 @@
32
32
  },
33
33
  "devDependencies": {
34
34
  "@type-challenges/utils": "~0.1.1",
35
- "@types/node": "16",
36
- "@typescript-eslint/eslint-plugin": "^5.40.1",
37
- "@typescript-eslint/parser": "^5.40.1",
35
+ "@types/node": "^16.18.0",
36
+ "@typescript-eslint/eslint-plugin": "^5.41.0",
37
+ "@typescript-eslint/parser": "^5.41.0",
38
38
  "bumpp": "^8.2.1",
39
39
  "common-types": "^1.31.1",
40
40
  "cross-env": "^7.0.3",
41
41
  "dd": "^0.24.0",
42
42
  "dotenv": "^16.0.3",
43
- "eslint": "^8.25.0",
43
+ "eslint": "^8.26.0",
44
44
  "eslint-config-prettier": "^8.5.0",
45
45
  "eslint-plugin-import": "^2.26.0",
46
46
  "eslint-plugin-prettier": "^4.2.1",
47
- "eslint-plugin-promise": "^6.1.0",
47
+ "eslint-plugin-promise": "^6.1.1",
48
48
  "npm-run-all": "~4.1.5",
49
49
  "prettier": "~2.7.1",
50
50
  "rimraf": "^3.0.2",
@@ -1,18 +1,23 @@
1
1
  /**
2
- * Maps from one type `I` to another `O`, where:
2
+ * **MapTo**
3
3
  *
4
- * - a **null** value indicates that there is no valid mapping for the given input
5
- * - you can either return a 1:1 or 1:M output as `O` or `O[]` when there is a mapping
4
+ * Maps from one type `I` to another `O[]`
6
5
  *
7
- * This type utility will ensure both `I` and `O` are honoured but if the runtime only
8
- * uses the type utility it's worth bearing in mind that while _typing_ will be as expected
9
- * the output parameter can assume properties that in fact do not reside
10
- *
11
- * ```ts
12
- * const mapper: ModelMapper<{title: string}, {title: string, kind: string}> = i => {
13
- * title: i.title,
14
- * kind: "markdown"
15
- * }
16
- * ```
6
+ * **Note:** because the output is an array you can easily support `1:1` and `1:M` mappings
7
+ * but not a filtering operation (e.g., `1:0`); if you need this then use `MapToWithFiltering`
8
+ * instead.
17
9
  */
18
10
  export type MapTo<I extends {}, O extends {}> = (i: I) => O[];
11
+
12
+ /**
13
+ * **MapToWithFiltering**
14
+ *
15
+ * Maps from one type `I` to another `(O | null)[]`
16
+ *
17
+ * **Note:** because the output is an array you can easily support `1:1` and `1:M` mappings
18
+ * and the allowance of the conversion to result in a `null` value also means that filter
19
+ * out an input value entirely is possible. If you don't need _filtering_ then use the
20
+ * `MapTo` type instead.
21
+ */
22
+
23
+ export type MapToWithFiltering<I extends {}, O extends {}> = (i: I) => O[] | null;
@@ -1,22 +1,37 @@
1
- import { MapTo } from "src/types/dictionary";
1
+ import { MapToWithFiltering } from "src/types/dictionary";
2
2
 
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 =
20
- <I extends {}, O extends {}>(cb: MapTo<I, O>) =>
21
- (source: I) =>
22
- cb(source);
29
+ <I extends {}, O extends {}>(cb: MapToWithFiltering<I, O>) =>
30
+ (source: I | I[]) => {
31
+ if (Array.isArray(source)) {
32
+ return source.flatMap((i) => cb(i)).filter((i) => i !== null) as O[];
33
+ } else {
34
+ const result = cb(source);
35
+ return result ? result : ([] as O[]);
36
+ }
37
+ };
@@ -6,6 +6,7 @@ import { mapTo } from "src/utility/dictionary/mapTo";
6
6
 
7
7
  type I = { title: string; color: string; products: string[] };
8
8
  const i: I = { title: "Test", color: "green", products: ["foo", "bar", "baz"] };
9
+ const i2: I = { title: "i2", color: "green", products: ["foo", "bar", "baz"] };
9
10
 
10
11
  type O = { title: string; count: number; unnecessary?: number };
11
12
 
@@ -103,4 +104,21 @@ describe("mapTo() utility function", () => {
103
104
  const cases: cases = [true];
104
105
  expect(cases).toBe(cases);
105
106
  });
107
+
108
+ it("test input filtering", () => {
109
+ const m = mapTo<I, O>((x) => {
110
+ return x.title === "i2"
111
+ ? null
112
+ : [
113
+ {
114
+ title: i.title,
115
+ count: i.products.length,
116
+ },
117
+ ];
118
+ });
119
+ const results = m([i, i2]);
120
+
121
+ expect(results).toHaveLength(1);
122
+ expect(results[0].title).toBe("Test");
123
+ });
106
124
  });