ts-essentials
Advanced tools
Comparing version 6.0.7 to 7.0.0
@@ -16,3 +16,6 @@ /** Essentials */ | ||
export declare type AnyArray<T = any> = Array<T> | ReadonlyArray<T>; | ||
/** Like Record, but can be used with only one argument */ | ||
/** | ||
* Like Record, but can be used with only one argument. | ||
* Useful, if you want to make sure that all of the keys of a finite type are used. | ||
*/ | ||
export declare type Dictionary<T, K extends string | number = string> = { | ||
@@ -24,7 +27,9 @@ [key in K]: T; | ||
/** | ||
* Like Dictionary, but ensures type safety of index access. | ||
* Note that only using an infinite type (`string` or `number`) as key type makes sense here, | ||
* because using `Dictionary<T, 'a' | 'b'>` already enforces that all of the keys are present. | ||
* Like Dictionary, but: | ||
* - ensures type safety of index access | ||
* - does not enforce key exhaustiveness | ||
*/ | ||
export declare type SafeDictionary<T, K extends string | number = string> = Dictionary<T | undefined, K>; | ||
export declare type SafeDictionary<T, K extends string | number = string> = { | ||
[key in K]?: T; | ||
}; | ||
/** Like Partial but recursive */ | ||
@@ -318,6 +323,9 @@ export declare type DeepPartial<T> = T extends Builtin | ||
: never; | ||
/** Easy create opaque types ie. types that are subset of their original types (ex: positive numbers, uppercased string) */ | ||
export declare type Opaque<K, T> = T & { | ||
__TYPE__: K; | ||
}; | ||
declare type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never; | ||
/** Easily create opaque types ie. types that are subset of their original types (ex: positive numbers, uppercased string) */ | ||
export declare type Opaque<Type, Token extends string> = Token extends StringLiteral<Token> | ||
? Type & { | ||
readonly __TYPE__: Token; | ||
} | ||
: never; | ||
/** Easily extract the type of a given object's values */ | ||
@@ -331,2 +339,7 @@ export declare type ValueOf<T> = T[keyof T]; | ||
export declare type AsyncOrSync<T> = PromiseLike<T> | T; | ||
export declare type Awaited<T> = T extends PromiseLike<infer PT> ? PT : never; | ||
export declare type AsyncOrSyncType<T> = T extends AsyncOrSync<infer PT> ? PT : never; | ||
export interface Newable<T> { | ||
new (...args: any[]): T; | ||
} | ||
declare type IsEqualConsideringWritability<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 | ||
@@ -333,0 +346,0 @@ ? true |
@@ -14,3 +14,3 @@ { | ||
], | ||
"version": "6.0.7", | ||
"version": "7.0.0", | ||
"main": "dist/index.js", | ||
@@ -17,0 +17,0 @@ "types": "dist/index.d.ts", |
@@ -9,3 +9,3 @@ <p align="center"> | ||
<a href="/package.json"><img alt="Software License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square"></a> | ||
<img src="https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square" alt="All Contributors"> | ||
<img src="https://img.shields.io/badge/all_contributors-26-orange.svg?style=flat-square" alt="All Contributors"> | ||
<a href="https://codechecks.io"><img src="https://raw.githubusercontent.com/codechecks/docs/master/images/badges/badge-default.svg?sanitize=true" alt="codechecks.io"></a> | ||
@@ -60,2 +60,4 @@ </p> | ||
- [AsyncOrSync type](#AsyncOrSync-type) | ||
- [Awaited type](#awaited-type) | ||
- [Newable](#newable) | ||
- [Assertions](#Assertions) | ||
@@ -105,2 +107,17 @@ - [Exact](#Exact) | ||
const value: number | undefined = safeDict["foo"]; | ||
// With SafeDictionary you don't need to use all of the sub-types of a finite type. | ||
// If you care about the key exhaustiveness, use a regular Dictionary. | ||
type ConfigKeys = "LOGLEVEL" | "PORT" | "DEBUG"; | ||
const configSafeDict: SafeDictionary<number, ConfigKeys> = { | ||
LOGLEVEL: 2, | ||
}; | ||
const maybePort: number | undefined = configSafeDict["PORT"]; | ||
const configDict: Dictionary<number, ConfigKeys> = { | ||
LOGLEVEL: 2, | ||
PORT: 8080, | ||
DEBUG: 1, | ||
}; | ||
const port: number = configDict["PORT"]; | ||
``` | ||
@@ -189,14 +206,13 @@ | ||
nested: { | ||
a: tryGet('a-value'), | ||
array: [{ bar: tryGet('bar-value') }] | ||
} | ||
} | ||
a: tryGet("a-value"), | ||
array: [{ bar: tryGet("bar-value") }], | ||
}, | ||
}; | ||
const sampleDeepUndefinable2: ComplexObjectUndefinable = { | ||
// error -- property `simple` missing, should be `number | undefined` | ||
nested: { | ||
array: [[{ bar: undefined }]] | ||
array: [[{ bar: undefined }]], | ||
// error -- property `a` missing, should be `string | undefined` | ||
} | ||
} | ||
}, | ||
}; | ||
``` | ||
@@ -557,3 +573,3 @@ | ||
}; | ||
type Result = OptionalKeys<T>; | ||
type Result = RequiredKeys<T>; | ||
// Result: | ||
@@ -578,11 +594,35 @@ // "a" | "c" | ||
Opaque types allow you to create unique type that can't be assigned to base type by accident. Good examples of opaque | ||
types include: | ||
- JWTs or other tokens - these are special kinds of string used for authorization purposes. If your app uses multiple | ||
types of tokens each should be a separate opaque type to avoid confusion. | ||
- specific currencies - amount of different currencies shouldn't be mixed | ||
- bitcoin address - special kind of string | ||
It's **critical** to understand that each token (second argument to `Opaque`) has to be unique across your codebase. | ||
We encourage you to leverage a pattern where you have single function to validate base type and create opaque type. | ||
```typescript | ||
type PositiveNumber = Opaque<number, "positive-number">; | ||
type PositiveNumber = Opaque<number, "PositiveNumber">; | ||
function makePositiveNumber(n: number): PositiveNumber { | ||
if (n <= 0) { | ||
throw new Error("Value not positive !!!"); | ||
throw new Error(`Value ${n} is not positive !`); | ||
} | ||
return (n as any) as PositiveNumber; // this ugly cast is required but only when "producing" opaque types | ||
} | ||
type NegativeNumber = Opaque<number, "NegativeNumber">; | ||
function makeNegativeNumber(n: number): NegativeNumber { | ||
if (n >= 0) { | ||
throw new Error(`Value ${n} is not negative !`); | ||
} | ||
return (n as any) as NegativeNumber; // this ugly cast is required but only when "producing" opaque types | ||
} | ||
let a = makePositiveNumber(5); // runtime check | ||
let b = makeNegativeNumber(-10); // runtime check | ||
a = b; // error at compile time | ||
``` | ||
@@ -668,4 +708,29 @@ | ||
} | ||
// to get original type use AsyncOrSyncType | ||
AsyncOrSyncType<AsyncOrSync<number>> // return 'number' | ||
``` | ||
### Awaited type | ||
Unwrap promised type: | ||
```typescript | ||
Awaited<Promise<number>> // number | ||
``` | ||
### Newable | ||
_keywords: constructor, class_ | ||
Type useful when working with classes (not their instances). | ||
```typescript | ||
class TestCls { | ||
constructor(arg1: string) {} | ||
} | ||
const t1: Newable<any> = TestCls; | ||
``` | ||
### Assertions | ||
@@ -782,2 +847,4 @@ | ||
<td align="center"><a href="https://github.com/bbarry"><img src="https://avatars0.githubusercontent.com/u/84951?v=4" width="100px;" alt=""/><br /><sub><b>Bill Barry</b></sub></a><br /><a href="https://github.com/krzkaczor/ts-essentials/commits?author=bbarry" title="Code">๐ป</a> <a href="https://github.com/krzkaczor/ts-essentials/commits?author=bbarry" title="Documentation">๐</a></td> | ||
<td align="center"><a href="https://github.com/akwodkiewicz"><img src="https://avatars2.githubusercontent.com/u/22861194?v=4" width="100px;" alt=""/><br /><sub><b>Andrzej Wรณdkiewicz</b></sub></a><br /><a href="https://github.com/krzkaczor/ts-essentials/commits?author=akwodkiewicz" title="Code">๐ป</a> <a href="https://github.com/krzkaczor/ts-essentials/commits?author=akwodkiewicz" title="Documentation">๐</a> <a href="#ideas-akwodkiewicz" title="Ideas, Planning, & Feedback">๐ค</a></td> | ||
<td align="center"><a href="http://chjdev.com"><img src="https://avatars2.githubusercontent.com/u/973941?v=4" width="100px;" alt=""/><br /><sub><b>Christian</b></sub></a><br /><a href="#ideas-chjdev" title="Ideas, Planning, & Feedback">๐ค</a></td> | ||
</tr> | ||
@@ -788,3 +855,2 @@ </table> | ||
<!-- prettier-ignore-end --> | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
@@ -791,0 +857,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
47553
411
851