type-fest 0.8.1 → 0.12.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/index.d.ts +7 -0
- package/license +1 -1
- package/package.json +11 -13
- package/readme.md +16 -11
- package/source/async-return-type.d.ts +23 -0
- package/source/basic.d.ts +2 -2
- package/source/conditional-except.d.ts +43 -0
- package/source/conditional-keys.d.ts +43 -0
- package/source/conditional-pick.d.ts +42 -0
- package/source/opaque.d.ts +30 -5
- package/source/package-json.d.ts +91 -7
- package/source/promise-value.d.ts +20 -0
- package/source/require-exactly-one.d.ts +0 -1
- package/source/set-optional.d.ts +3 -1
- package/source/set-required.d.ts +3 -1
- package/source/tsconfig-json.d.ts +872 -0
- package/source/union-to-intersection.d.ts +58 -0
package/index.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ export {Promisable} from './source/promisable';
|
|
|
15
15
|
export {Opaque} from './source/opaque';
|
|
16
16
|
export {SetOptional} from './source/set-optional';
|
|
17
17
|
export {SetRequired} from './source/set-required';
|
|
18
|
+
export {PromiseValue} from './source/promise-value';
|
|
19
|
+
export {AsyncReturnType} from './source/async-return-type';
|
|
20
|
+
export {ConditionalExcept} from './source/conditional-except';
|
|
21
|
+
export {ConditionalKeys} from './source/conditional-keys';
|
|
22
|
+
export {ConditionalPick} from './source/conditional-pick';
|
|
23
|
+
export {UnionToIntersection} from './source/union-to-intersection';
|
|
18
24
|
|
|
19
25
|
// Miscellaneous
|
|
20
26
|
export {PackageJson} from './source/package-json';
|
|
27
|
+
export {TsConfigJson} from './source/tsconfig-json';
|
package/license
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
3
|
+
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https:/sindresorhus.com)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "type-fest",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "A collection of essential TypeScript types",
|
|
5
5
|
"license": "(MIT OR CC0-1.0)",
|
|
6
6
|
"repository": "sindresorhus/type-fest",
|
|
7
|
+
"funding": "https://github.com/sponsors/sindresorhus",
|
|
7
8
|
"author": {
|
|
8
9
|
"name": "Sindre Sorhus",
|
|
9
10
|
"email": "sindresorhus@gmail.com",
|
|
10
|
-
"url": "sindresorhus.com"
|
|
11
|
+
"url": "https://sindresorhus.com"
|
|
11
12
|
},
|
|
12
13
|
"engines": {
|
|
13
|
-
"node": ">=
|
|
14
|
+
"node": ">=10"
|
|
14
15
|
},
|
|
15
16
|
"scripts": {
|
|
16
17
|
"test": "xo && tsd"
|
|
@@ -31,20 +32,17 @@
|
|
|
31
32
|
"json"
|
|
32
33
|
],
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@sindresorhus/tsconfig": "^0.
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^2.
|
|
36
|
-
"@typescript-eslint/parser": "^2.
|
|
37
|
-
"eslint-config-xo-typescript": "^0.
|
|
35
|
+
"@sindresorhus/tsconfig": "^0.7.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^2.22.0",
|
|
37
|
+
"@typescript-eslint/parser": "^2.22.0",
|
|
38
|
+
"eslint-config-xo-typescript": "^0.26.0",
|
|
38
39
|
"tsd": "^0.7.3",
|
|
39
|
-
"
|
|
40
|
+
"typescript": "^3.8.3",
|
|
41
|
+
"xo": "^0.27.2"
|
|
40
42
|
},
|
|
43
|
+
"types": "index.d.ts",
|
|
41
44
|
"xo": {
|
|
42
|
-
"extends": "xo-typescript",
|
|
43
|
-
"extensions": [
|
|
44
|
-
"ts"
|
|
45
|
-
],
|
|
46
45
|
"rules": {
|
|
47
|
-
"import/no-unresolved": "off",
|
|
48
46
|
"@typescript-eslint/indent": "off"
|
|
49
47
|
}
|
|
50
48
|
}
|
package/readme.md
CHANGED
|
@@ -23,7 +23,6 @@ Either add this package as a dependency or copy-paste the needed types. No credi
|
|
|
23
23
|
|
|
24
24
|
PR welcome for additional commonly needed types and docs improvements. Read the [contributing guidelines](.github/contributing.md) first.
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
## Install
|
|
28
27
|
|
|
29
28
|
```
|
|
@@ -32,7 +31,6 @@ $ npm install type-fest
|
|
|
32
31
|
|
|
33
32
|
*Requires TypeScript >=3.2*
|
|
34
33
|
|
|
35
|
-
|
|
36
34
|
## Usage
|
|
37
35
|
|
|
38
36
|
```ts
|
|
@@ -47,7 +45,6 @@ type FooWithoutRainbow = Except<Foo, 'rainbow'>;
|
|
|
47
45
|
//=> {unicorn: string}
|
|
48
46
|
```
|
|
49
47
|
|
|
50
|
-
|
|
51
48
|
## API
|
|
52
49
|
|
|
53
50
|
Click the type names for complete docs.
|
|
@@ -69,7 +66,7 @@ Click the type names for complete docs.
|
|
|
69
66
|
- [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type.
|
|
70
67
|
- [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys.
|
|
71
68
|
- [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys.
|
|
72
|
-
- [`RequireExactlyOne`](source/require-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more.
|
|
69
|
+
- [`RequireExactlyOne`](source/require-exactly-one.d.ts) - Create a type that requires exactly a single key of the given keys and disallows more.
|
|
73
70
|
- [`PartialDeep`](source/partial-deep.d.ts) - Create a deeply optional version of another type. Use [`Partial<T>`](https://github.com/Microsoft/TypeScript/blob/2961bc3fc0ea1117d4e53bc8e97fa76119bc33e3/src/lib/es5.d.ts#L1401-L1406) if you only need one level deep.
|
|
74
71
|
- [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of an `object`/`Map`/`Set`/`Array` type. Use [`Readonly<T>`](https://github.com/Microsoft/TypeScript/blob/2961bc3fc0ea1117d4e53bc8e97fa76119bc33e3/src/lib/es5.d.ts#L1415-L1420) if you only need one level deep.
|
|
75
72
|
- [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729).
|
|
@@ -77,11 +74,17 @@ Click the type names for complete docs.
|
|
|
77
74
|
- [`Opaque`](source/opaque.d.ts) - Create an [opaque type](https://codemix.com/opaque-types-in-javascript/).
|
|
78
75
|
- [`SetOptional`](source/set-optional.d.ts) - Create a type that makes the given keys optional.
|
|
79
76
|
- [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required.
|
|
77
|
+
- [`PromiseValue`](source/promise-value.d.ts) - Returns the type that is wrapped inside a `Promise`.
|
|
78
|
+
- [`AsyncReturnType`](source/async-return-type.d.ts) - Unwrap the return type of a function that returns a `Promise`.
|
|
79
|
+
- [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type.
|
|
80
|
+
- [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type.
|
|
81
|
+
- [`ConditionalExcept`](source/conditional-except.d.ts) - Like `Omit` except it removes properties from a shape where the values extend the given `Condition` type.
|
|
82
|
+
- [`UnionToIntersection`](source/union-to-intersection.d.ts) - Convert a union type to an intersection type.
|
|
80
83
|
|
|
81
84
|
### Miscellaneous
|
|
82
85
|
|
|
83
86
|
- [`PackageJson`](source/package-json.d.ts) - Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file).
|
|
84
|
-
|
|
87
|
+
- [`TsConfigJson`](source/tsconfig-json.d.ts) - Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) (TypeScript 3.7).
|
|
85
88
|
|
|
86
89
|
## Declined types
|
|
87
90
|
|
|
@@ -89,7 +92,8 @@ Click the type names for complete docs.
|
|
|
89
92
|
|
|
90
93
|
- [`Diff` and `Spread`](https://github.com/sindresorhus/type-fest/pull/7) - The PR author didn't provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider.
|
|
91
94
|
- [`Dictionary`](https://github.com/sindresorhus/type-fest/issues/33) - You only save a few characters (`Dictionary<number>` vs `Record<string, number>`) from [`Record`](https://github.com/Microsoft/TypeScript/blob/2961bc3fc0ea1117d4e53bc8e97fa76119bc33e3/src/lib/es5.d.ts#L1429-L1434), which is more flexible and well-known. Also, you shouldn't use an object as a dictionary. We have `Map` in JavaScript now.
|
|
92
|
-
|
|
95
|
+
- [`SubType`](https://github.com/sindresorhus/type-fest/issues/22) - The type is powerful, but lacks good use-cases and is prone to misuse.
|
|
96
|
+
- [`ExtractProperties` and `ExtractMethods`](https://github.com/sindresorhus/type-fest/pull/4) - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies.
|
|
93
97
|
|
|
94
98
|
## Tips
|
|
95
99
|
|
|
@@ -103,7 +107,7 @@ There are many advanced types most users don't know about.
|
|
|
103
107
|
Example
|
|
104
108
|
</summary>
|
|
105
109
|
|
|
106
|
-
[Playground](https://
|
|
110
|
+
[Playground](https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgHIHsAmEDC6QzADmyA3gLABQyycADnanALYQBcyAzmFKEQNxUaddFDAcQAV2YAjaIMoBfKlQQAbOJ05osEAIIMAQpOBrsUMkOR1eANziRkCfISKSoD4Pg4ZseAsTIALyW1DS0DEysHADkvvoMMQA0VsKi4sgAzAAMuVaKClY2wPaOknSYDrguADwA0sgQAB6QIJjaANYQAJ7oMDp+LsQAfAAUXd0cdUnI9mo+uv6uANp1ALoAlKHhyGAAFsCcAHTOAW4eYF4gyxNrwbNwago0ypRWp66jH8QcAApwYmAjxq8SWIy2FDCNDA3ToKFBQyIdR69wmfQG1TOhShyBgomQX3w3GQE2Q6IA8jIAFYQBBgI4TTiEs5bTQYsFInrLTbbHZOIlgZDlSqQABqj0kKBC3yINx6a2xfOQwH6o2FVXFaklwSCIUkbQghBAEEwENSfNOlykEGefNe5uhB2O6sgS3GPRmLogmslG1tLxUOKgEDA7hAuydtteryAA)
|
|
107
111
|
|
|
108
112
|
```ts
|
|
109
113
|
interface NodeConfig {
|
|
@@ -117,6 +121,10 @@ There are many advanced types most users don't know about.
|
|
|
117
121
|
port: 3000
|
|
118
122
|
};
|
|
119
123
|
|
|
124
|
+
private updateConfig<Key extends keyof NodeConfig>(key: Key, value: NodeConfig[Key]) {
|
|
125
|
+
this.configuration[key] = value;
|
|
126
|
+
}
|
|
127
|
+
|
|
120
128
|
config(config: Partial<NodeConfig>) {
|
|
121
129
|
type NodeConfigKey = keyof NodeConfig;
|
|
122
130
|
|
|
@@ -127,7 +135,7 @@ There are many advanced types most users don't know about.
|
|
|
127
135
|
continue;
|
|
128
136
|
}
|
|
129
137
|
|
|
130
|
-
this.
|
|
138
|
+
this.updateConfig(key, updateValue);
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
return this;
|
|
@@ -609,19 +617,16 @@ There are many advanced types most users don't know about.
|
|
|
609
617
|
|
|
610
618
|
You can find some examples in the [TypeScript docs](https://www.typescriptlang.org/docs/handbook/advanced-types.html#predefined-conditional-types).
|
|
611
619
|
|
|
612
|
-
|
|
613
620
|
## Maintainers
|
|
614
621
|
|
|
615
622
|
- [Sindre Sorhus](https://github.com/sindresorhus)
|
|
616
623
|
- [Jarek Radosz](https://github.com/CvX)
|
|
617
624
|
- [Dimitri Benin](https://github.com/BendingBender)
|
|
618
625
|
|
|
619
|
-
|
|
620
626
|
## License
|
|
621
627
|
|
|
622
628
|
(MIT OR CC0-1.0)
|
|
623
629
|
|
|
624
|
-
|
|
625
630
|
---
|
|
626
631
|
|
|
627
632
|
<div align="center">
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {PromiseValue} from './promise-value';
|
|
2
|
+
|
|
3
|
+
type AsyncFunction = (...args: unknown[]) => Promise<unknown>;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Unwrap the return type of a function that returns a `Promise`.
|
|
7
|
+
|
|
8
|
+
There has been [discussion](https://github.com/microsoft/TypeScript/pull/35998) about implementing this type in TypeScript.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```ts
|
|
12
|
+
import {AsyncReturnType} from 'type-fest';
|
|
13
|
+
import {asyncFunction} from 'api';
|
|
14
|
+
|
|
15
|
+
// This type resolves to the unwrapped return type of `asyncFunction`.
|
|
16
|
+
type Value = AsyncReturnType<typeof asyncFunction>;
|
|
17
|
+
|
|
18
|
+
async function doSomething(value: Value) {}
|
|
19
|
+
|
|
20
|
+
asyncFunction().then(value => doSomething(value));
|
|
21
|
+
```
|
|
22
|
+
*/
|
|
23
|
+
export type AsyncReturnType<Target extends AsyncFunction> = PromiseValue<ReturnType<Target>>;
|
package/source/basic.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type Primitive =
|
|
|
17
17
|
/**
|
|
18
18
|
Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
|
|
19
19
|
*/
|
|
20
|
-
export type Class<T = unknown, Arguments extends any[] = any[]> = new(...arguments_: Arguments) => T;
|
|
20
|
+
export type Class<T = unknown, Arguments extends any[] = any[]> = new(...arguments_: Arguments) => T; // eslint-disable-line @typescript-eslint/type-annotation-spacing
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`.
|
|
@@ -40,7 +40,7 @@ Matches a JSON object.
|
|
|
40
40
|
|
|
41
41
|
This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.
|
|
42
42
|
*/
|
|
43
|
-
export type JsonObject = {[
|
|
43
|
+
export type JsonObject = {[Key in string]?: JsonValue};
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
Matches a JSON array.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {Except} from './except';
|
|
2
|
+
import {ConditionalKeys} from './conditional-keys';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Exclude keys from a shape that matches the given `Condition`.
|
|
6
|
+
|
|
7
|
+
This is useful when you want to create a new type with a specific set of keys from a shape. For example, you might want to exclude all the primitive properties from a class and form a new shape containing everything but the primitive properties.
|
|
8
|
+
|
|
9
|
+
@example
|
|
10
|
+
```
|
|
11
|
+
import {Primitive, ConditionalExcept} from 'type-fest';
|
|
12
|
+
|
|
13
|
+
class Awesome {
|
|
14
|
+
name: string;
|
|
15
|
+
successes: number;
|
|
16
|
+
failures: bigint;
|
|
17
|
+
|
|
18
|
+
run() {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ExceptPrimitivesFromAwesome = ConditionalExcept<Awesome, Primitive>;
|
|
22
|
+
//=> {run: () => void}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
```
|
|
27
|
+
import {ConditionalExcept} from 'type-fest';
|
|
28
|
+
|
|
29
|
+
interface Example {
|
|
30
|
+
a: string;
|
|
31
|
+
b: string | number;
|
|
32
|
+
c: () => void;
|
|
33
|
+
d: {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type NonStringKeysOnly = ConditionalExcept<Example, string>;
|
|
37
|
+
//=> {b: string | number; c: () => void; d: {}}
|
|
38
|
+
```
|
|
39
|
+
*/
|
|
40
|
+
export type ConditionalExcept<Base, Condition> = Except<
|
|
41
|
+
Base,
|
|
42
|
+
ConditionalKeys<Base, Condition>
|
|
43
|
+
>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Extract the keys from a type where the value type of the key extends the given `Condition`.
|
|
3
|
+
|
|
4
|
+
Internally this is used for the `ConditionalPick` and `ConditionalExcept` types.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import {ConditionalKeys} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
interface Example {
|
|
11
|
+
a: string;
|
|
12
|
+
b: string | number;
|
|
13
|
+
c?: string;
|
|
14
|
+
d: {};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type StringKeysOnly = ConditionalKeys<Example, string>;
|
|
18
|
+
//=> 'a'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
To support partial types, make sure your `Condition` is a union of undefined (for example, `string | undefined`) as demonstrated below.
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
```
|
|
25
|
+
type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
|
|
26
|
+
//=> 'a' | 'c'
|
|
27
|
+
```
|
|
28
|
+
*/
|
|
29
|
+
export type ConditionalKeys<Base, Condition> = NonNullable<
|
|
30
|
+
// Wrap in `NonNullable` to strip away the `undefined` type from the produced union.
|
|
31
|
+
{
|
|
32
|
+
// Map through all the keys of the given base type.
|
|
33
|
+
[Key in keyof Base]:
|
|
34
|
+
// Pick only keys with types extending the given `Condition` type.
|
|
35
|
+
Base[Key] extends Condition
|
|
36
|
+
// Retain this key since the condition passes.
|
|
37
|
+
? Key
|
|
38
|
+
// Discard this key since the condition fails.
|
|
39
|
+
: never;
|
|
40
|
+
|
|
41
|
+
// Convert the produced object into a union type of the keys which passed the conditional test.
|
|
42
|
+
}[keyof Base]
|
|
43
|
+
>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {ConditionalKeys} from './conditional-keys';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Pick keys from the shape that matches the given `Condition`.
|
|
5
|
+
|
|
6
|
+
This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import {Primitive, ConditionalPick} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
class Awesome {
|
|
13
|
+
name: string;
|
|
14
|
+
successes: number;
|
|
15
|
+
failures: bigint;
|
|
16
|
+
|
|
17
|
+
run() {}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type PickPrimitivesFromAwesome = ConditionalPick<Awesome, Primitive>;
|
|
21
|
+
//=> {name: string; successes: number; failures: bigint}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
@example
|
|
25
|
+
```
|
|
26
|
+
import {ConditionalPick} from 'type-fest';
|
|
27
|
+
|
|
28
|
+
interface Example {
|
|
29
|
+
a: string;
|
|
30
|
+
b: string | number;
|
|
31
|
+
c: () => void;
|
|
32
|
+
d: {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type StringKeysOnly = ConditionalPick<Example, string>;
|
|
36
|
+
//=> {a: string}
|
|
37
|
+
```
|
|
38
|
+
*/
|
|
39
|
+
export type ConditionalPick<Base, Condition> = Pick<
|
|
40
|
+
Base,
|
|
41
|
+
ConditionalKeys<Base, Condition>
|
|
42
|
+
>;
|
package/source/opaque.d.ts
CHANGED
|
@@ -13,9 +13,28 @@ There have been several discussions about adding this feature to TypeScript via
|
|
|
13
13
|
```
|
|
14
14
|
import {Opaque} from 'type-fest';
|
|
15
15
|
|
|
16
|
-
type AccountNumber = Opaque<number>;
|
|
17
|
-
type AccountBalance = Opaque<number>;
|
|
16
|
+
type AccountNumber = Opaque<number, 'AccountNumber'>;
|
|
17
|
+
type AccountBalance = Opaque<number, 'AccountBalance'>;
|
|
18
18
|
|
|
19
|
+
// The Token parameter allows the compiler to differentiate between types, whereas "unknown" will not. For example, consider the following structures:
|
|
20
|
+
type ThingOne = Opaque<string>;
|
|
21
|
+
type ThingTwo = Opaque<string>;
|
|
22
|
+
|
|
23
|
+
// To the compiler, these types are allowed to be cast to each other as they have the same underlying type. They are both `string & { __opaque__: unknown }`.
|
|
24
|
+
// To avoid this behaviour, you would instead pass the "Token" parameter, like so.
|
|
25
|
+
type NewThingOne = Opaque<string, 'ThingOne'>;
|
|
26
|
+
type NewThingTwo = Opaque<string, 'ThingTwo'>;
|
|
27
|
+
|
|
28
|
+
// Now they're completely separate types, so the following will fail to compile.
|
|
29
|
+
function createNewThingOne (): NewThingOne {
|
|
30
|
+
// As you can see, casting from a string is still allowed. However, you may not cast NewThingOne to NewThingTwo, and vice versa.
|
|
31
|
+
return 'new thing one' as NewThingOne;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// This will fail to compile, as they are fundamentally different types.
|
|
35
|
+
const thingTwo = createNewThingOne() as NewThingTwo;
|
|
36
|
+
|
|
37
|
+
// Here's another example of opaque typing.
|
|
19
38
|
function createAccountNumber(): AccountNumber {
|
|
20
39
|
return 2 as AccountNumber;
|
|
21
40
|
}
|
|
@@ -33,8 +52,14 @@ getMoneyForAccount(2);
|
|
|
33
52
|
// You can use opaque values like they aren't opaque too.
|
|
34
53
|
const accountNumber = createAccountNumber();
|
|
35
54
|
|
|
36
|
-
// This will compile successfully.
|
|
37
|
-
accountNumber + 2;
|
|
55
|
+
// This will not compile successfully.
|
|
56
|
+
const newAccountNumber = accountNumber + 2;
|
|
57
|
+
|
|
58
|
+
// As a side note, you can (and should) use recursive types for your opaque types to make them stronger and hopefully easier to type.
|
|
59
|
+
type Person = {
|
|
60
|
+
id: Opaque<number, Person>;
|
|
61
|
+
name: string;
|
|
62
|
+
};
|
|
38
63
|
```
|
|
39
64
|
*/
|
|
40
|
-
export type Opaque<Type> = Type & {readonly __opaque__:
|
|
65
|
+
export type Opaque<Type, Token = unknown> = Type & {readonly __opaque__: Token};
|
package/source/package-json.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ declare namespace PackageJson {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export interface DirectoryLocations {
|
|
30
|
+
[directoryType: string]: unknown;
|
|
31
|
+
|
|
30
32
|
/**
|
|
31
33
|
Location for executable scripts. Sugar to generate entries in the `bin` property by walking the folder.
|
|
32
34
|
*/
|
|
@@ -56,8 +58,6 @@ declare namespace PackageJson {
|
|
|
56
58
|
Location for test files.
|
|
57
59
|
*/
|
|
58
60
|
test?: string;
|
|
59
|
-
|
|
60
|
-
[directoryType: string]: unknown;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export type Scripts = {
|
|
@@ -223,9 +223,9 @@ declare namespace PackageJson {
|
|
|
223
223
|
esnext?:
|
|
224
224
|
| string
|
|
225
225
|
| {
|
|
226
|
+
[moduleName: string]: string | undefined;
|
|
226
227
|
main?: string;
|
|
227
228
|
browser?: string;
|
|
228
|
-
[moduleName: string]: string | undefined;
|
|
229
229
|
};
|
|
230
230
|
|
|
231
231
|
/**
|
|
@@ -236,6 +236,13 @@ declare namespace PackageJson {
|
|
|
236
236
|
| {
|
|
237
237
|
[moduleName: string]: string | false;
|
|
238
238
|
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
Denote which files in your project are "pure" and therefore safe for Webpack to prune if unused.
|
|
242
|
+
|
|
243
|
+
[Read more.](https://webpack.js.org/guides/tree-shaking/)
|
|
244
|
+
*/
|
|
245
|
+
sideEffects?: boolean | string[];
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
export interface TypeScriptConfiguration {
|
|
@@ -250,11 +257,48 @@ declare namespace PackageJson {
|
|
|
250
257
|
typings?: string;
|
|
251
258
|
}
|
|
252
259
|
|
|
260
|
+
/**
|
|
261
|
+
An alternative configuration for Yarn workspaces.
|
|
262
|
+
*/
|
|
263
|
+
export interface WorkspaceConfig {
|
|
264
|
+
/**
|
|
265
|
+
An array of workspace pattern strings which contain the workspace packages.
|
|
266
|
+
*/
|
|
267
|
+
packages?: WorkspacePattern[];
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
Designed to solve the problem of packages which break when their `node_modules` are moved to the root workspace directory - a process known as hoisting. For these packages, both within your workspace, and also some that have been installed via `node_modules`, it is important to have a mechanism for preventing the default Yarn workspace behavior. By adding workspace pattern strings here, Yarn will resume non-workspace behavior for any package which matches the defined patterns.
|
|
271
|
+
|
|
272
|
+
[Read more](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/)
|
|
273
|
+
*/
|
|
274
|
+
nohoist?: WorkspacePattern[];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
A workspace pattern points to a directory or group of directories which contain packages that should be included in the workspace installation process.
|
|
279
|
+
|
|
280
|
+
The patterns are handled with [minimatch](https://github.com/isaacs/minimatch).
|
|
281
|
+
|
|
282
|
+
@example
|
|
283
|
+
`docs` → Include the docs directory and install its dependencies.
|
|
284
|
+
`packages/*` → Include all nested directories within the packages directory, like `packages/cli` and `packages/core`.
|
|
285
|
+
*/
|
|
286
|
+
type WorkspacePattern = string;
|
|
287
|
+
|
|
253
288
|
export interface YarnConfiguration {
|
|
254
289
|
/**
|
|
255
|
-
|
|
290
|
+
Used to configure [Yarn workspaces](https://classic.yarnpkg.com/docs/workspaces/).
|
|
256
291
|
|
|
257
|
-
|
|
292
|
+
Workspaces allow you to manage multiple packages within the same repository in such a way that you only need to run `yarn install` once to install all of them in a single pass.
|
|
293
|
+
|
|
294
|
+
Please note that the top-level `private` property of `package.json` **must** be set to `true` in order to use workspaces.
|
|
295
|
+
*/
|
|
296
|
+
workspaces?: WorkspacePattern[] | WorkspaceConfig;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
If your package only allows one version of a given dependency, and you’d like to enforce the same behavior as `yarn install --flat` on the command-line, set this to `true`.
|
|
300
|
+
|
|
301
|
+
Note that if your `package.json` contains `"flat": true` and other packages depend on yours (e.g. you are building a library rather than an app), those other packages will also need `"flat": true` in their `package.json` or be installed with `yarn install --flat` on the command-line.
|
|
258
302
|
*/
|
|
259
303
|
flat?: boolean;
|
|
260
304
|
|
|
@@ -368,6 +412,13 @@ export type PackageJson = {
|
|
|
368
412
|
| {
|
|
369
413
|
type: string;
|
|
370
414
|
url: string;
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
Relative path to package.json if it is placed in non-root directory (for example if it is part of a monorepo).
|
|
418
|
+
|
|
419
|
+
[Read more.](https://github.com/npm/rfcs/blob/latest/implemented/0010-monorepo-subdirectory-declaration.md)
|
|
420
|
+
*/
|
|
421
|
+
directory?: string;
|
|
371
422
|
};
|
|
372
423
|
|
|
373
424
|
/**
|
|
@@ -402,6 +453,15 @@ export type PackageJson = {
|
|
|
402
453
|
*/
|
|
403
454
|
peerDependencies?: PackageJson.Dependency;
|
|
404
455
|
|
|
456
|
+
/**
|
|
457
|
+
Indicate peer dependencies that are optional.
|
|
458
|
+
*/
|
|
459
|
+
peerDependenciesMeta?: {
|
|
460
|
+
[packageName: string]: {
|
|
461
|
+
optional: true;
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
|
|
405
465
|
/**
|
|
406
466
|
Package names that are bundled when the package is published.
|
|
407
467
|
*/
|
|
@@ -487,11 +547,35 @@ export type PackageJson = {
|
|
|
487
547
|
private?: boolean;
|
|
488
548
|
|
|
489
549
|
/**
|
|
490
|
-
|
|
491
|
-
|
|
550
|
+
A set of config values that will be used at publish-time. It's especially handy to set the tag, registry or access, to ensure that a given package is not tagged with 'latest', published to the global public registry or that a scoped module is private by default.
|
|
551
|
+
*/
|
|
492
552
|
publishConfig?: {
|
|
493
553
|
[config: string]: unknown;
|
|
494
554
|
};
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
Describes and notifies consumers of a package's monetary support information.
|
|
558
|
+
|
|
559
|
+
[Read more.](https://github.com/npm/rfcs/blob/latest/accepted/0017-add-funding-support.md)
|
|
560
|
+
*/
|
|
561
|
+
funding?: string | {
|
|
562
|
+
/**
|
|
563
|
+
The type of funding.
|
|
564
|
+
*/
|
|
565
|
+
type?: LiteralUnion<
|
|
566
|
+
| 'github'
|
|
567
|
+
| 'opencollective'
|
|
568
|
+
| 'patreon'
|
|
569
|
+
| 'individual'
|
|
570
|
+
| 'foundation'
|
|
571
|
+
| 'corporation',
|
|
572
|
+
string
|
|
573
|
+
>;
|
|
574
|
+
/**
|
|
575
|
+
The URL to the funding page.
|
|
576
|
+
*/
|
|
577
|
+
url: string;
|
|
578
|
+
};
|
|
495
579
|
} &
|
|
496
580
|
PackageJson.NonStandardEntryPoints &
|
|
497
581
|
PackageJson.TypeScriptConfiguration &
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Returns the type that is wrapped inside a `Promise` type.
|
|
3
|
+
If the type is not a `Promise`, the type itself is returned.
|
|
4
|
+
|
|
5
|
+
@example
|
|
6
|
+
```
|
|
7
|
+
import {PromiseValue} from 'type-fest';
|
|
8
|
+
|
|
9
|
+
type AsyncData = Promise<string>;
|
|
10
|
+
let asyncData: PromiseValue<AsyncData> = Promise.resolve('ABC');
|
|
11
|
+
|
|
12
|
+
type Data = PromiseValue<AsyncData>;
|
|
13
|
+
let data: Data = await asyncData;
|
|
14
|
+
|
|
15
|
+
// Here's an example that shows how this type reacts to non-Promise types.
|
|
16
|
+
type SyncData = PromiseValue<string>;
|
|
17
|
+
let syncData: SyncData = getSyncData();
|
|
18
|
+
```
|
|
19
|
+
*/
|
|
20
|
+
export type PromiseValue<PromiseType, Otherwise = PromiseType> = PromiseType extends Promise<infer Value> ? Value : Otherwise;
|
package/source/set-optional.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Except} from './except';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type.
|
|
3
5
|
|
|
@@ -23,7 +25,7 @@ type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
|
|
|
23
25
|
*/
|
|
24
26
|
export type SetOptional<BaseType, Keys extends keyof BaseType = keyof BaseType> =
|
|
25
27
|
// Pick just the keys that are not optional from the base type.
|
|
26
|
-
|
|
28
|
+
Except<BaseType, Keys> &
|
|
27
29
|
// Pick the keys that should be optional from the base type and make them optional.
|
|
28
30
|
Partial<Pick<BaseType, Keys>> extends
|
|
29
31
|
// If `InferredType` extends the previous, then for each key, use the inferred type key.
|
package/source/set-required.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Except} from './except';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.
|
|
3
5
|
|
|
@@ -23,7 +25,7 @@ type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
|
|
|
23
25
|
*/
|
|
24
26
|
export type SetRequired<BaseType, Keys extends keyof BaseType = keyof BaseType> =
|
|
25
27
|
// Pick just the keys that are not required from the base type.
|
|
26
|
-
|
|
28
|
+
Except<BaseType, Keys> &
|
|
27
29
|
// Pick the keys that should be required from the base type and make them required.
|
|
28
30
|
Required<Pick<BaseType, Keys>> extends
|
|
29
31
|
// If `InferredType` extends the previous, then for each key, use the inferred type key.
|