type-plus 4.9.0 → 4.9.1

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Homa Wong (unional) (homawong@gmail.com)
3
+ Copyright © 2018 Homa Wong (unional) (homawong@gmail.com)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![NPM version][npm-image]][npm-url]
4
4
  [![NPM downloads][downloads-image]][downloads-url]
5
5
 
6
- [![Github NodeJS][github-nodejs]][github-action-url]
6
+ [![GitHub NodeJS][github-nodejs]][github-action-url]
7
7
  [![Codecov][codecov-image]][codecov-url]
8
8
 
9
9
  [![Semantic Release][semantic-release-image]][semantic-release-url]
@@ -11,7 +11,7 @@
11
11
  [![Visual Studio Code][vscode-image]][vscode-url]
12
12
  [![Wallaby.js][wallaby-image]][wallaby-url]
13
13
 
14
- Provides additional types and type adjusted utilities for [TypeScript](https://www.typescriptlang.org/).
14
+ Provides additional types and type adjusted utilities for [TypeScript].
15
15
 
16
16
  ## Feature Highlights
17
17
 
@@ -39,7 +39,7 @@ There are 5 kinds of type assertions:
39
39
  - `type guard`: [User-defined type guard functions](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) (`if (isBool(s))`) introduced in TypeScript 1.6.
40
40
  - `assertion function`: [assertion functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) (`assertIsBool(a)`) introduced in TypeScript 3.7.
41
41
  - `logical`: functions or generic types that returns `true` or `false` type to be used in type level programming.
42
- - `filter`: generic types that returns `never` if the test fails.
42
+ - `filter`: generic type that returns `never` if the test fails.
43
43
 
44
44
  Here are the type assertions provided in `type-plus`.
45
45
  Use the one that fits your specific needs.
@@ -175,7 +175,7 @@ You need to specify `T`.
175
175
 
176
176
  ✔️ `immediate`, `runtime`
177
177
 
178
- It can used as type check: `isType.t<Equal<A, B>>()`,
178
+ It can be used as type check: `isType.t<Equal<A, B>>()`,
179
179
  or value type check: `isType.t(valueTypeIsTrue)`.
180
180
  It returns `true` when passes (which is the only case when used in TypeScript).
181
181
 
@@ -183,7 +183,7 @@ It returns `true` when passes (which is the only case when used in TypeScript).
183
183
 
184
184
  ✔️ `immediate`, `runtime`
185
185
 
186
- It can used as type check: `isType.f<Equal<A, B>>()`,
186
+ It can be used as type check: `isType.f<Equal<A, B>>()`,
187
187
  or value type check: `isType.f(valueTypeIsFalse)`.
188
188
  It returns `true` when passes (which is the only case when used in TypeScript).
189
189
 
@@ -288,14 +288,14 @@ type No = IsAny<1, 'yes', 'no'> // 'no'
288
288
  - `DropLast<A>`: drops the last value type of `A`.
289
289
  - `DropMatch<A, Criteria>`: drops entries matching `Criteria` in array or tuple `A`.
290
290
  - `DropUndefined<A>`: drop undefined entries from array of tuple `A`.
291
- - `Filter<A, Criteria>`: filter the array or tuple `A`, keeping entries satisfying `Criteria`. **deprecated. Renaming to `KeepMatch`**
291
+ - `Filter<A, Criteria>`: filter the array or tuple `A`, keeping entries satisfying `Criteria`. **Deprecated. Renaming to `KeepMatch`**
292
292
  - `FindFirst<A, Criteria>`: gets the first type satisfying `Criteria`.
293
293
  - `FindLast<A, Criteria>`: gets the last type satisfying `Criteria`.
294
294
  - `Head<A>`: gets the first entry in the array.
295
295
  - `IntersectOfProps<A, K>`: gets the intersect of `A[K]` types (deprecate `MapToProp`)
296
296
  - `IsArray<T>`: `logical` predicate for `Array`.
297
297
  - `KeepMatch<A, Criteria>`: keeps entries satisfying `Criteria` in array or tuple `A`.
298
- - `Last<A>`: gets the last type of an array or tuple.
298
+ - `Last<A>`: gets the last type of array or tuple.
299
299
  - `literalArray(...entries)`: return an array whose items are restricted to the provided literals.
300
300
  - `PadLeft<A, Total, PadWith>`: pads `A` with `PadWith` if the length of `A` is less than `L`.
301
301
  - `reduceWhile()`: `reduce()` with predicate for early termination. \
@@ -319,7 +319,7 @@ type No = IsAny<1, 'yes', 'no'> // 'no'
319
319
  - `JSONObject`: JSON object
320
320
  - `JSONArray`: JSON array
321
321
  - `JSONTypes`: all JSON compatible types.
322
- - `JSONTypes.get<T>(obj, ...props)`: get a cast value in json
322
+ - `JSONTypes.get<T>(obj, ...props)`: get a cast value in JSON
323
323
 
324
324
  ```ts
325
325
  import { JSONTypes } from 'type-plus'
@@ -341,7 +341,7 @@ JSONTypes.get<string>(someJson, 'a', 'b', 1, 'c') // miku
341
341
  - `mapKey()`: type adjusted map by key.
342
342
  - `reduceByKey()`: type adjusted reduce by key.
343
343
  - `someKey()`: type adjusted some by key.
344
- - `SpreadRecord<A, B>`: type for `{...a, ...b}` when both `a` and `b` are `Record`. \
344
+ - `SpreadRecord<A, B>`: type for `{...a, ...b}` when both `a` and `b` are `Record`\
345
345
  for array, just do `[...A, ...B]`.
346
346
 
347
347
  ### Promise function
@@ -418,7 +418,7 @@ So you may encounter some weird behavior if your logic is complex.
418
418
  - `Max<A, B, Fail=never>`: `max(A, B)`, for whole number, `Fail` otherwise.
419
419
  - `GreaterThan<A, B, Fail=never>`: `A > B` for whole numbers, `Fail` otherwise.
420
420
 
421
- #### Arithmetics
421
+ #### Arithmetic
422
422
 
423
423
  - `Add<A, B, Fail=never>`: `A + B` for positive and whole numbers, `Fail` otherwise.
424
424
  - `Subtract<A, B, Fail=never>`: `A - B` for positive and whole numbers, `Fail` otherwise.
@@ -433,10 +433,10 @@ So you may encounter some weird behavior if your logic is complex.
433
433
  - `hasKey()`: function of `HasKey`.
434
434
  - `hasProperty(value, prop)`: assert `value` has property `prop`. This will pick the correct union type.
435
435
  - `isConstructor(subject)`: type guard `subject` is a constructor.
436
- - `isSystemError(code, err)`: type guard `err` with Nodejs error code.
436
+ - `isSystemError(code, err)`: type guard `err` with NodeJS error code.
437
437
  - `omit(obj, ...props)`: omit properties from `obj`.
438
438
  - `pick(obj, ...props)`: pick properties from `obj`.
439
- - `record<K, V>(value?)`: create a `Record<K, V>` without extra object prototype.
439
+ - `record<K, V>(value?)`: create a `Record<K, V>` without extra object prototype.
440
440
  - `required(...)`: merge options and removing `Partial<T>`. From [`unpartial`](https://github.com/unional/unpartial)
441
441
  - `requiredDeep(...)`: merge options deeply and removing `Partial<T>`. From [`unpartial`](https://github.com/unional/unpartial)
442
442
  - `split(target, ...splitters)`: split one object into multiple objects.
@@ -528,8 +528,8 @@ nominalMatch(b1, b2) // false
528
528
 
529
529
  ## Attribution
530
530
 
531
- Some of the code in this library is created by other people in the TypeScript community.
532
- I merely adding them in and maybe making some adjustments.
531
+ Some code in this library is created by other people in the TypeScript community.
532
+ I'm merely adding them in and maybe making some adjustments.
533
533
  Whenever possible, I add attribution to the person who created those **codes** in the file.
534
534
 
535
535
  ## Similar projects
@@ -539,7 +539,7 @@ Whenever possible, I add attribution to the person who created those **codes** i
539
539
  - [`type-fest`](https://github.com/sindresorhus/type-fest), a collection of essential TypeScript types.
540
540
  - [`type-zoo`](https://github.com/pelotom/type-zoo), a modest type lib usable today.
541
541
  - [`typepark`](https://github.com/kgtkr/typepark), a new type collection offering tuple manipulation and `Pipe`.
542
- - [`typelevel-ts`](https://github.com/gcanti/typelevel-ts), a type lib by [@gcanti](https://github.com/gcanti), author of several FP libs in TS.
542
+ - [`typelevel-ts`](https://github.com/gcanti/typelevel-ts), a type lib by [@gcanti](https://github.com/gcanti), author of several FP libraries in TS.
543
543
  - [`typical`](https://github.com/KiaraGrouwstra/typical), a playground of type-level operations for TypeScript.
544
544
 
545
545
  ## Contribute
@@ -563,12 +563,13 @@ git push
563
563
  [codecov-url]: https://codecov.io/gh/unional/type-plus
564
564
  [downloads-image]: https://img.shields.io/npm/dm/type-plus.svg?style=flat
565
565
  [downloads-url]: https://npmjs.org/package/type-plus
566
- [github-nodejs]: https://github.com/unional/type-plus/workflows/nodejs/badge.svg
567
566
  [github-action-url]: https://github.com/unional/type-plus/actions
567
+ [github-nodejs]: https://github.com/unional/type-plus/workflows/nodejs/badge.svg
568
568
  [npm-image]: https://img.shields.io/npm/v/type-plus.svg?style=flat
569
569
  [npm-url]: https://npmjs.org/package/type-plus
570
570
  [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
571
571
  [semantic-release-url]: https://github.com/semantic-release/semantic-release
572
+ [TypeScript]: https://www.typescriptlang.org
572
573
  [vscode-image]: https://img.shields.io/badge/vscode-ready-green.svg
573
574
  [vscode-url]: https://code.visualstudio.com/
574
575
  [wallaby-image]: https://img.shields.io/badge/wallaby.js-configured-green.svg
@@ -1 +1 @@
1
- {"version":3,"file":"drop.js","sourceRoot":"","sources":["../../ts/array/drop.ts"],"names":[],"mappings":";;;AAqEA,SAAgB,IAAI,CAAoC,KAAQ,EAAE,KAAQ;IACxE,OAAO,KAAK,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,KAAK,EAAX,CAAW,CAAQ,CAAA;AAC9C,CAAC;AAFD,oBAEC"}
1
+ {"version":3,"file":"drop.js","sourceRoot":"","sources":["../../ts/array/drop.ts"],"names":[],"mappings":";;;AAqEA,SAAgB,IAAI,CAAoC,KAAQ,EAAE,KAAQ;IACxE,OAAO,KAAK,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,KAAK,EAAX,CAAW,CAAoB,CAAA;AAC1D,CAAC;AAFD,oBAEC"}
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../ts/functional/compose.ts"],"names":[],"mappings":";;;AAMA,SAAgB,OAAO;IAA2B,aAAU;SAAV,UAAU,EAAV,qBAAU,EAAV,IAAU;QAAV,wBAAU;;IAC1D,OAAO;QAAC,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAAK,OAAA,GAAG,CAAC,MAAM,CAAC,UAAC,IAAI,EAAE,EAAE,IAAK,OAAA,CAAC,EAAE,eAAI,IAAI,EAAE,EAAb,CAAa,EAAE,IAAI,CAAC,CAAC,CAAC,CAAQ;IAAvD,CAAuD,CAAA;AACpF,CAAC;AAFD,0BAEC"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../ts/functional/compose.ts"],"names":[],"mappings":";;;AAMA,SAAgB,OAAO;IAA2B,aAAU;SAAV,UAAU,EAAV,qBAAU,EAAV,IAAU;QAAV,wBAAU;;IAE1D,OAAO;QAAC,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAAK,OAAA,GAAG,CAAC,MAAM,CAAC,UAAC,IAAI,EAAE,EAAE,IAAK,OAAA,CAAC,EAAE,eAAI,IAAI,EAAE,EAAb,CAAa,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAAhD,CAAgD,CAAA;AAC7E,CAAC;AAHD,0BAGC"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.record = void 0;
4
4
  function record(value) {
5
5
  var r = Object.create(null);
6
- return value ? Object.assign(r, value) : r;
6
+ return (value ? Object.assign(r, value) : r);
7
7
  }
8
8
  exports.record = record;
9
9
  //# sourceMappingURL=record.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"record.js","sourceRoot":"","sources":["../../ts/object/record.ts"],"names":[],"mappings":";;;AAMA,SAAgB,MAAM,CAAwB,KAAoB;IAChE,IAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5C,CAAC;AAHD,wBAGC"}
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../ts/object/record.ts"],"names":[],"mappings":";;;AAOA,SAAgB,MAAM,CAAwB,KAAoB;IAChE,IAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAc,CAAA;IAC1C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAwB,CAAA;AACrE,CAAC;AAHD,wBAGC"}
@@ -1 +1 @@
1
- {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,yCAAyC;AA+LzC,SAAgB,KAAK,CAAC,MAAiB;IAAE,mBAAyB;SAAzB,UAAyB,EAAzB,qBAAyB,EAAzB,IAAyB;QAAzB,kCAAyB;;IAChE,IAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,IAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,IAAA,uBAAW,EACtC,CAAC,EACD,UAAC,CAAC,EAAE,CAAC,YAAK,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAA,MAAM,CAAC,CAAC,CAAC,mCAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,EAAA,EAC1D,EAAe,CAAC,EAHW,CAGX,CAAC,CAAA;IACnB,IAAM,CAAC,GAAG,IAAA,uBAAW,EAAC,MAAM,EAAE,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAArC,CAAqC,EAAE,EAAe,CAAC,CAAA;IAC/F,uCAAW,CAAC,UAAE,CAAC,UAAC;AAClB,CAAC;AARD,sBAQC"}
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,yCAAyC;AA+LzC,SAAgB,KAAK,CAAC,MAAiB;IAAE,mBAAyB;SAAzB,UAAyB,EAAzB,qBAAyB,EAAzB,IAAyB;QAAzB,kCAAyB;;IAChE,IAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,IAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,IAAA,uBAAW,EACtC,CAAC,EACD,UAAC,CAAC,EAAE,CAAC,YAAK,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAA,MAAM,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,EAAA,EACzD,EAAe,CAAC,EAHW,CAGX,CAAC,CAAA;IACnB,IAAM,CAAC,GAAG,IAAA,uBAAW,EAAC,MAAM,EAAE,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAArC,CAAqC,EAAE,EAAe,CAAC,CAAA;IAC/F,uCAAW,CAAC,UAAE,CAAC,UAAC;AAClB,CAAC;AARD,sBAQC"}
@@ -1 +1 @@
1
- {"version":3,"file":"drop.js","sourceRoot":"","sources":["../../ts/array/drop.ts"],"names":[],"mappings":"AAqEA,MAAM,UAAU,IAAI,CAAoC,KAAQ,EAAE,KAAQ;IACxE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAQ,CAAA;AAC9C,CAAC"}
1
+ {"version":3,"file":"drop.js","sourceRoot":"","sources":["../../ts/array/drop.ts"],"names":[],"mappings":"AAqEA,MAAM,UAAU,IAAI,CAAoC,KAAQ,EAAE,KAAQ;IACxE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAoB,CAAA;AAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../ts/functional/compose.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,OAAO,CAA2B,GAAG,GAAO;IAC1D,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAQ,CAAA;AACpF,CAAC"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../ts/functional/compose.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,OAAO,CAA2B,GAAG,GAAO;IAE1D,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7E,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export function record(value) {
2
2
  const r = Object.create(null);
3
- return value ? Object.assign(r, value) : r;
3
+ return (value ? Object.assign(r, value) : r);
4
4
  }
5
5
  //# sourceMappingURL=record.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"record.js","sourceRoot":"","sources":["../../ts/object/record.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,MAAM,CAAwB,KAAoB;IAChE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5C,CAAC"}
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../ts/object/record.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,MAAM,CAAwB,KAAoB;IAChE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAc,CAAA;IAC1C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAwB,CAAA;AACrE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA+LzC,MAAM,UAAU,KAAK,CAAC,MAAiB,EAAE,GAAG,SAAsB;IAChE,MAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CACtC,CAAC,EACD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1D,EAAe,CAAC,CAAC,CAAA;IACnB,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAe,CAAC,CAAA;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AAClB,CAAC"}
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA+LzC,MAAM,UAAU,KAAK,CAAC,MAAiB,EAAE,GAAG,SAAsB;IAChE,MAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CACtC,CAAC,EACD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EACzD,EAAe,CAAC,CAAC,CAAA;IACnB,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAe,CAAC,CAAA;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-plus",
3
- "version": "4.9.0",
3
+ "version": "4.9.1",
4
4
  "description": "Provides additional types for TypeScript.",
5
5
  "homepage": "https://github.com/unional/type-plus",
6
6
  "bugs": {
@@ -63,15 +63,17 @@
63
63
  "@semantic-release/changelog": "^6.0.1",
64
64
  "@size-limit/preset-small-lib": "^7.0.8",
65
65
  "@types/jest": "^27.4.1",
66
+ "@typescript-eslint/eslint-plugin": "^5.23.0",
67
+ "@typescript-eslint/parser": "^5.23.0",
66
68
  "@unional/fixture": "^1.8.0",
67
69
  "assertron": "^9.0.4",
68
70
  "dependency-check": "^4.1.0",
69
71
  "eslint": "^8.11.0",
70
- "eslint-plugin-harmony": "^6.0.0",
71
- "husky": "^7.0.0",
72
- "jest": "^27.5.1",
72
+ "eslint-plugin-harmony": "^7.0.1",
73
+ "husky": "^8.0.0",
74
+ "jest": "^28.0.0",
73
75
  "jest-progress-tracker": "^3.0.3",
74
- "jest-validate": "^27.5.1",
76
+ "jest-validate": "^28.0.0",
75
77
  "jest-watch-repeat": "^2.0.0",
76
78
  "jest-watch-suspend": "^1.1.2",
77
79
  "jest-watch-toggle-config": "^2.0.1",
package/ts/array/drop.ts CHANGED
@@ -68,5 +68,5 @@ export type DropUndefined<A extends Array<any>> = DropMatch<A, undefined>
68
68
  * drop a particular value from an array
69
69
  */
70
70
  export function drop<A extends Readonly<Array<any>>, C>(array: A, value: C): DropMatch<A, C> {
71
- return array.filter(v => v !== value) as any
71
+ return array.filter(v => v !== value) as DropMatch<A, C>
72
72
  }
@@ -11,7 +11,7 @@ test('works with endofunctors: +2 *3', () => {
11
11
  })
12
12
 
13
13
  test('cross types', () => {
14
- const n2s = (n: number) => '' + n
14
+ const n2s = (n: number) => String(n)
15
15
  const len1 = (s: string) => s.length === 1
16
16
 
17
17
  const isSingleDigit = compose(n2s, len1)
@@ -5,5 +5,6 @@ import { AnyFunction } from '../function/AnyFunction'
5
5
  * compose functions
6
6
  */
7
7
  export function compose<FS extends AnyFunction[]>(...fns: FS): (...args: Parameters<Head<FS>>) => ReturnType<Last<FS>> {
8
- return (...args: any[]) => fns.reduce((args, fn) => [fn(...args)], args)[0] as any
8
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
9
+ return (...args: any[]) => fns.reduce((args, fn) => [fn(...args)], args)[0]
9
10
  }
@@ -1,10 +1,11 @@
1
1
  import { KeyTypes } from 'type-plus'
2
2
  import { Widen } from '../utils'
3
+ import { AnyRecord } from './AnyRecord'
3
4
 
4
5
  /**
5
6
  * Creates a `Record<Key, Value>`
6
7
  */
7
8
  export function record<K extends KeyTypes, V>(value?: Record<K, V>): Record<Widen<K>, V> {
8
- const r = Object.create(null)
9
- return value ? Object.assign(r, value) : r
9
+ const r = Object.create(null) as AnyRecord
10
+ return (value ? Object.assign(r, value) : r) as Record<Widen<K>, V>
10
11
  }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
1
2
  import { AnyRecord } from './AnyRecord'
2
3
  import { Omit } from './omit'
3
4
  import { reduceByKey } from './reduceKey'
@@ -195,7 +196,7 @@ export function split(target: AnyRecord, ...splitters: AnyRecord[]): AnyRecord[]
195
196
  const keyMap: AnyRecord = {}
196
197
  const s = splitters.map(s => reduceByKey(
197
198
  s,
198
- (p, k) => (keyMap[k] = true, p[k] = target[k] ?? s[k], p),
199
+ (p, k) => (keyMap[k] = true, p[k] = target[k] ?? s[k], p),
199
200
  {} as AnyRecord))
200
201
  const r = reduceByKey(target, (p, k) => keyMap[k] ? p : (p[k] = target[k], p), {} as AnyRecord)
201
202
  return [...s, r]
@@ -1,5 +1,7 @@
1
1
  {
2
2
  "rules": {
3
- "@typescript-eslint/ban-types": "off"
3
+ "@typescript-eslint/ban-types": "off",
4
+ "@typescript-eslint/no-unsafe-assignment": "off",
5
+ "@typescript-eslint/no-unsafe-return": "off"
4
6
  }
5
7
  }
@@ -30,5 +30,5 @@ export const BooleanSpec: TypeSpec<Type<'boolean', boolean>> = {
30
30
  return value === actual ? { type: 'boolean', value } : { type: 'boolean', value, fail: true }
31
31
  }
32
32
  },
33
- toNative(value: any): true { return value as any }
33
+ toNative(value: any): true { return value }
34
34
  }
@@ -1,5 +1,7 @@
1
1
  {
2
2
  "rules": {
3
- "@typescript-eslint/ban-types": "off"
3
+ "@typescript-eslint/ban-types": "off",
4
+ "@typescript-eslint/no-unsafe-assignment": "off",
5
+ "@typescript-eslint/no-unsafe-return": "off"
4
6
  }
5
7
  }
package/ts/types/Tuple.ts CHANGED
@@ -1,50 +1,50 @@
1
- import { TypeAnalysis, Type } from './types'
2
- import { AllType } from './AllType'
3
- import { undef, Undefined } from './Undefined'
4
- import { union, Union } from './Union'
5
- import { Tail } from '../array'
6
-
7
- export type Tuple<Values extends AllType[] = any[]> = Type<'tuple', Values>
8
-
9
- export namespace Tuple {
10
- export type Analysis<
11
- Value extends AllType.PrimitiveValues | AllType.Analysis = any
12
- > = TypeAnalysis<'tuple', Value[]>
13
-
14
- export type FindByProp<
15
- Tuple extends Array<{ [K in Key]: any }>,
16
- Key extends string,
17
- Value> = FindByProp._<Tuple, Key, Value>['result']
18
- export namespace FindByProp {
19
- export type _<Tuple extends Array<{ [K in Key]: any }>, Key extends string, Value> = Tuple['length'] extends 0
20
- ? { result: never }
21
- : { result: Value extends Tuple[0][Key] ? Tuple[0] : _<Tail<Tuple>, Key, Value>['result'] }
22
- }
23
- }
24
-
25
- /**
26
- * Creates a tuple type.
27
- */
28
- function create<Value extends AllType, Values extends AllType[]>(
29
- value: Value,
30
- ...values: Values
31
- ): Tuple<[Value, ...Values]> {
32
- return {
33
- type: 'tuple',
34
- value: [value, ...values]
35
- }
36
- }
37
- export const tuple = {
38
- create,
39
- optional: {
40
- /**
41
- * Creates an optional tuple type.
42
- */
43
- create<Value extends AllType, Values extends AllType[]>(
44
- value: Value,
45
- ...values: Values
46
- ): Union<[Tuple<[Value, ...Values]>, Undefined]> {
47
- return union.create(create(value, ...values), undef)
48
- }
49
- }
50
- }
1
+ import { TypeAnalysis, Type } from './types'
2
+ import { AllType } from './AllType'
3
+ import { undef, Undefined } from './Undefined'
4
+ import { union, Union } from './Union'
5
+ import { Tail } from '../array'
6
+
7
+ export type Tuple<Values extends AllType[] = any[]> = Type<'tuple', Values>
8
+
9
+ export namespace Tuple {
10
+ export type Analysis<
11
+ Value extends AllType.PrimitiveValues | AllType.Analysis = any
12
+ > = TypeAnalysis<'tuple', Value[]>
13
+
14
+ export type FindByProp<
15
+ Tuple extends Array<{ [K in Key]: any }>,
16
+ Key extends string,
17
+ Value> = FindByProp._<Tuple, Key, Value>['result']
18
+ export namespace FindByProp {
19
+ export type _<Tuple extends Array<{ [K in Key]: any }>, Key extends string, Value> = Tuple['length'] extends 0
20
+ ? { result: never }
21
+ : { result: Value extends Tuple[0][Key] ? Tuple[0] : _<Tail<Tuple>, Key, Value>['result'] }
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Creates a tuple type.
27
+ */
28
+ function create<Value extends AllType, Values extends AllType[]>(
29
+ value: Value,
30
+ ...values: Values
31
+ ): Tuple<[Value, ...Values]> {
32
+ return {
33
+ type: 'tuple',
34
+ value: [value, ...values]
35
+ }
36
+ }
37
+ export const tuple = {
38
+ create,
39
+ optional: {
40
+ /**
41
+ * Creates an optional tuple type.
42
+ */
43
+ create<Value extends AllType, Values extends AllType[]>(
44
+ value: Value,
45
+ ...values: Values
46
+ ): Union<[Tuple<[Value, ...Values]>, Undefined]> {
47
+ return union.create(create(value, ...values), undef)
48
+ }
49
+ }
50
+ }
@@ -36,15 +36,15 @@ export function analyzeInternal(options: analyze.Options, type: AllType, actual:
36
36
  return typeof actual === t ? ok(type) : fail(t)
37
37
  case 'null':
38
38
  return actual === null ? ok(type) : fail(t)
39
- case 'boolean': return analyzeBoolean(type as Boolean, actual)
40
- case 'number': return analyzeType(number, type as Number, actual)
41
- case 'string': return analyzeType(string, type as String, actual)
39
+ case 'boolean': return analyzeBoolean(type, actual)
40
+ case 'number': return analyzeType(number, type, actual)
41
+ case 'string': return analyzeType(string, type, actual)
42
42
  // case 'bigint': return analyzeType(bigint, type as BigInt, actual)
43
- case 'object': return analyzeObject(options, type as ObjectType, actual)
44
- case 'record': return analyzeRecord(options, type as RecordType, actual)
45
- case 'array': return analyzeArray(options, type as ArrayType, actual)
46
- case 'tuple': return analyzeTuple(options, type as Tuple, actual)
47
- case 'union': return analyzeUnion(options, type as Union, actual)
43
+ case 'object': return analyzeObject(options, type, actual)
44
+ case 'record': return analyzeRecord(options, type, actual)
45
+ case 'array': return analyzeArray(options, type, actual)
46
+ case 'tuple': return analyzeTuple(options, type, actual)
47
+ case 'union': return analyzeUnion(options, type, actual)
48
48
  }
49
49
  }
50
50
 
@@ -63,7 +63,7 @@ function analyzeType(
63
63
  type: Type<any, any>,
64
64
  actual: unknown
65
65
  ) {
66
- const value = type['value']
66
+ const value = type.value
67
67
  return typeof actual === baseType['type'] && (type === baseType || actual === value)
68
68
  ? ok(type)
69
69
  : fail(type['type'], type['value'])
@@ -80,7 +80,7 @@ function analyzeArray(options: analyze.Options, type: ArrayType<AllType>, actual
80
80
  if (!Array.isArray(actual)) return fail('array', subType ? ok(subType) : undefined)
81
81
  if (subType === undefined) return ok(type)
82
82
 
83
- const r = actual.reduce((p, a, i) => {
83
+ const r = actual.reduce((p: { keys: number[], actual: any[], value: any }, a, i) => {
84
84
  const r = analyzeInternal(options, subType, a)
85
85
  if (r.fail) {
86
86
  p.value = r.value
@@ -237,6 +237,17 @@ describe('tuple', () => {
237
237
  ].join('\n')
238
238
  )
239
239
  })
240
+ test('strict with more than 2 extra', () => {
241
+ assertReportEquals(
242
+ strict,
243
+ T.tuple.create(T.null, T.number),
244
+ [null, 1, 'a', false, true],
245
+ [
246
+ `subject expects to be strictly [null,number] but is actually [null, 1, 'a', false, true]`,
247
+ `indices 2..4 should not contain any value`
248
+ ].join('\n')
249
+ )
250
+ })
240
251
  })
241
252
  describe('object', () => {
242
253
  test('not object', () => {
@@ -1,115 +1,115 @@
1
- import { tersify } from 'tersify'
2
- import { reduceByKey } from '../object'
3
- import { AllType } from './AllType'
4
- import { analyze } from './analyze'
5
-
6
- export function getPlainAnalysisReport(analysisResult: analyze.Result) {
7
- if (!analysisResult.analysis.fail) {
8
- return `The subject${analysisResult.options.strict ? ' strictly' : ''} satisfies type ${formatAnalysis(analysisResult.analysis)}`
9
- }
10
-
11
- return toViolations(analysisResult.options, [], analysisResult.actual, analysisResult.analysis).join('\n')
12
- }
13
-
14
- function formatAnalysis(a: AllType.Analysis) {
15
- return a.type
16
- }
17
-
18
- function toViolations(options: analyze.Options, path: Array<string | number>, actual: any, analysis: AllType.Analysis): string[] {
19
- const clause = options.strict ? `expects to be strictly` : `expects to be`
20
- const violations = [`${formatPath(path)} ${clause} ${formatType(analysis)} but is actually ${tersify(actual)}`]
21
-
22
- switch (analysis.type) {
23
- case 'tuple': {
24
- if (options.strict && analysis.value!.length < actual.length) {
25
- const index = actual.length - analysis.value!.length === 1 ? 'index' : 'indices'
26
- violations.push(`${index} ${range(analysis.value!.length, actual.length)} should not contain any value`)
27
- }
28
- const v2 = analysis.value!.reduce((p, a, i) => {
29
- if (a.fail) p.push(...toViolations(options, [...path, i], actual[i], a))
30
- return p
31
- }, [] as string[])
32
- if (v2.length > 0) violations.push(...v2)
33
- break
34
- }
35
- case 'object':
36
- if (analysis.value) {
37
- const typeKeys = Object.keys(analysis.value)
38
- const actualKeys = Object.keys(actual)
39
- if (options.strict) {
40
- const extraKeys = actualKeys.filter(k => typeKeys.indexOf(k) === -1)
41
- const index = extraKeys.length === 1 ? 'property' : 'properties'
42
- violations.push(`${index} ${extraKeys.join(',')} should not contain any value`)
43
- }
44
- const propViolations = typeKeys.reduce((p, k) => {
45
- const a = analysis.value![k]
46
- if (a.fail) p.push(...toViolations(options, [...path, k], actual[k], a))
47
- return p
48
- }, [] as string[])
49
- if (propViolations.length > 0) violations.push(...propViolations)
50
- }
51
- break
52
- }
53
- return violations
54
- }
55
-
56
- function formatPath(path: Array<string | number>) {
57
- return path.length === 0 ? 'subject' : `subject${path.map(p => toAccessor(p)).join('')}`
58
- }
59
-
60
- function toAccessor(p: string | number) {
61
- if (typeof p === 'number') return `[${p}]`
62
- if (p.indexOf('-') >= 0) return `['${p}']`
63
- return `.${p}`
64
- }
65
-
66
- function toProp(p: string) {
67
- return p.indexOf('-') >= 0 ? `'${p}'` : p
68
- }
69
-
70
- function formatType(e: AllType.Analysis): string {
71
- switch (e.type) {
72
- case 'undefined':
73
- case 'null':
74
- case 'symbol':
75
- // case 'never':
76
- return e.type
77
- case 'boolean':
78
- case 'number':
79
- // case 'bigint':
80
- return e.value === undefined ? e.type : String(e.value)
81
- case 'string':
82
- return e.value === undefined ? e.type : `'${e.value}'`
83
- case 'array':
84
- return e.value === undefined ? 'Array<any>' : `Array<${formatType(e.value as any)}>`
85
- case 'tuple':
86
- return `[${formatExpectations(e.value as AllType.Analysis[])}]`
87
- case 'object':
88
- return e.value === undefined ? e.type
89
- : `{ ${reduceByKey(
90
- e.value as Record<string, any>,
91
- (p, k) => {
92
- p.push(`${toProp(k)}: ${formatType((e.value as any)[k] as any)}`)
93
- return p
94
- },
95
- [] as string[]
96
- ).join(', ')} }`
97
- case 'record':
98
- return `Record<string, ${formatType(e.value as any)}>`
99
- case 'union':
100
- return `(${formatExpectations(e.value as AllType.Analysis[], ' | ')})`
101
- // istanbul ignore next
102
- default:
103
- return `report not expected: ${e.value}`
104
- }
105
- }
106
-
107
- function formatExpectations(es: AllType.Analysis[], sep = ',') {
108
- return es.map(formatType).join(sep)
109
- }
110
-
111
- function range(start: number, end: number) {
112
- const r: number[] = []
113
- while (start < end) r.push(start++)
114
- return r
115
- }
1
+ import { tersify } from 'tersify'
2
+ import { reduceByKey } from '../object'
3
+ import { AllType } from './AllType'
4
+ import { analyze } from './analyze'
5
+
6
+ export function getPlainAnalysisReport(analysisResult: analyze.Result) {
7
+ if (!analysisResult.analysis.fail) {
8
+ return `The subject${analysisResult.options.strict ? ' strictly' : ''} satisfies type ${formatAnalysis(analysisResult.analysis)}`
9
+ }
10
+
11
+ return toViolations(analysisResult.options, [], analysisResult.actual, analysisResult.analysis).join('\n')
12
+ }
13
+
14
+ function formatAnalysis(a: AllType.Analysis) {
15
+ return a.type
16
+ }
17
+
18
+ function toViolations(options: analyze.Options, path: Array<string | number>, actual: any, analysis: AllType.Analysis): string[] {
19
+ const clause = options.strict ? `expects to be strictly` : `expects to be`
20
+ const violations = [`${formatPath(path)} ${clause} ${formatType(analysis)} but is actually ${tersify(actual)}`]
21
+
22
+ switch (analysis.type) {
23
+ case 'tuple': {
24
+ if (options.strict && analysis.value!.length < actual.length) {
25
+ violations.push(`${range(analysis.value!.length, actual.length)} should not contain any value`)
26
+ }
27
+ const v2 = analysis.value!.reduce((p: string[], a, i) => {
28
+ if (a.fail) p.push(...toViolations(options, [...path, i], actual[i], a))
29
+ return p
30
+ }, [])
31
+ if (v2.length > 0) violations.push(...v2)
32
+ break
33
+ }
34
+ case 'object':
35
+ if (analysis.value) {
36
+ const typeKeys = Object.keys(analysis.value)
37
+ const actualKeys = Object.keys(actual)
38
+ if (options.strict) {
39
+ const extraKeys = actualKeys.filter(k => typeKeys.indexOf(k) === -1)
40
+ const index = extraKeys.length === 1 ? 'property' : 'properties'
41
+ violations.push(`${index} ${extraKeys.join(',')} should not contain any value`)
42
+ }
43
+ const propViolations = typeKeys.reduce((p, k) => {
44
+ const a = analysis.value![k]
45
+ if (a.fail) p.push(...toViolations(options, [...path, k], actual[k], a))
46
+ return p
47
+ }, [] as string[])
48
+ if (propViolations.length > 0) violations.push(...propViolations)
49
+ }
50
+ break
51
+ }
52
+ return violations
53
+ }
54
+
55
+ function formatPath(path: Array<string | number>) {
56
+ return path.length === 0 ? 'subject' : `subject${path.map(p => toAccessor(p)).join('')}`
57
+ }
58
+
59
+ function toAccessor(p: string | number) {
60
+ if (typeof p === 'number') return `[${p}]`
61
+ if (p.indexOf('-') >= 0) return `['${p}']`
62
+ return `.${p}`
63
+ }
64
+
65
+ function toProp(p: string) {
66
+ return p.indexOf('-') >= 0 ? `'${p}'` : p
67
+ }
68
+
69
+ function formatType(e: AllType.Analysis): string {
70
+ switch (e.type) {
71
+ case 'undefined':
72
+ case 'null':
73
+ case 'symbol':
74
+ // case 'never':
75
+ return e.type
76
+ case 'boolean':
77
+ case 'number':
78
+ // case 'bigint':
79
+ return e.value === undefined ? e.type : String(e.value)
80
+ case 'string':
81
+ return e.value === undefined ? e.type : `'${e.value}'`
82
+ case 'array':
83
+ return e.value === undefined ? 'Array<any>' : `Array<${formatType(e.value)}>`
84
+ case 'tuple':
85
+ return `[${formatExpectations(e.value as AllType.Analysis[])}]`
86
+ case 'object':
87
+ return e.value === undefined ? e.type
88
+ : `{ ${reduceByKey(
89
+ e.value,
90
+ (p, k) => {
91
+ p.push(`${toProp(k)}: ${formatType((e.value as any)[k])}`)
92
+ return p
93
+ },
94
+ [] as string[]
95
+ ).join(', ')} }`
96
+ case 'record':
97
+ return `Record<string, ${formatType(e.value)}>`
98
+ case 'union':
99
+ return `(${formatExpectations(e.value as AllType.Analysis[], ' | ')})`
100
+ // istanbul ignore next
101
+ default:
102
+ return `report not expected: ${e.type}`
103
+ }
104
+ }
105
+
106
+ function formatExpectations(es: AllType.Analysis[], sep = ',') {
107
+ return es.map(formatType).join(sep)
108
+ }
109
+
110
+ function range(start: number, end: number) {
111
+ const diff = end - start
112
+ if (diff === 1) return `index ${start}`
113
+ if (diff === 2) return `indices ${start},${end - 1}`
114
+ return `indices ${start}..${end - 1}`
115
+ }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
1
2
  import { amend, as, asAny, isType } from '..'
2
3
 
3
4
  describe('as<T>()', () => {