type-fest 3.3.0 → 3.4.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 +1 -0
- package/package.json +1 -1
- package/readme.md +13 -12
- package/source/async-return-type.d.ts +1 -1
- package/source/asyncify.d.ts +1 -1
- package/source/exact.d.ts +8 -21
- package/source/global-this.d.ts +21 -0
- package/source/internal.d.ts +27 -1
- package/source/jsonify.d.ts +2 -2
- package/source/set-return-type.d.ts +5 -8
package/index.d.ts
CHANGED
|
@@ -101,5 +101,6 @@ export type {Get} from './source/get';
|
|
|
101
101
|
export type {LastArrayElement} from './source/last-array-element';
|
|
102
102
|
|
|
103
103
|
// Miscellaneous
|
|
104
|
+
export type {GlobalThis} from './source/global-this';
|
|
104
105
|
export type {PackageJson} from './source/package-json';
|
|
105
106
|
export type {TsConfigJson} from './source/tsconfig-json';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -236,6 +236,7 @@ Click the type names for complete docs.
|
|
|
236
236
|
|
|
237
237
|
### Miscellaneous
|
|
238
238
|
|
|
239
|
+
- [`GlobalThis`](source/global-this.d.ts) - Declare locally scoped properties on `globalThis`.
|
|
239
240
|
- [`PackageJson`](source/package-json.d.ts) - Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). It also includes support for [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) and [Yarn Workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/).
|
|
240
241
|
- [`TsConfigJson`](source/tsconfig-json.d.ts) - Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
|
|
241
242
|
|
|
@@ -623,13 +624,13 @@ There are many advanced types most users don't know about.
|
|
|
623
624
|
// Mutate array randomly changing its' elements indexes.
|
|
624
625
|
}
|
|
625
626
|
|
|
626
|
-
function callNTimes<Fn extends (...
|
|
627
|
+
function callNTimes<Fn extends (...arguments_: any[]) => any> (func: Fn, callCount: number) {
|
|
627
628
|
// Type that represents the type of the received function parameters.
|
|
628
629
|
type FunctionParameters = Parameters<Fn>;
|
|
629
630
|
|
|
630
|
-
return function (...
|
|
631
|
+
return function (...arguments_: FunctionParameters) {
|
|
631
632
|
for (let i = 0; i < callCount; i++) {
|
|
632
|
-
func(...
|
|
633
|
+
func(...arguments_);
|
|
633
634
|
}
|
|
634
635
|
}
|
|
635
636
|
}
|
|
@@ -656,7 +657,7 @@ There are many advanced types most users don't know about.
|
|
|
656
657
|
}
|
|
657
658
|
}
|
|
658
659
|
|
|
659
|
-
class InstanceCache<T extends (new (...
|
|
660
|
+
class InstanceCache<T extends (new (...arguments_: any[]) => any)> {
|
|
660
661
|
private ClassConstructor: T;
|
|
661
662
|
private cache: Map<string, InstanceType<T>> = new Map();
|
|
662
663
|
|
|
@@ -664,18 +665,18 @@ There are many advanced types most users don't know about.
|
|
|
664
665
|
this.ClassConstructor = ctr;
|
|
665
666
|
}
|
|
666
667
|
|
|
667
|
-
getInstance (...
|
|
668
|
-
const hash = this.calculateArgumentsHash(...
|
|
668
|
+
getInstance (...arguments_: ConstructorParameters<T>): InstanceType<T> {
|
|
669
|
+
const hash = this.calculateArgumentsHash(...arguments_);
|
|
669
670
|
|
|
670
671
|
const existingInstance = this.cache.get(hash);
|
|
671
672
|
if (existingInstance !== undefined) {
|
|
672
673
|
return existingInstance;
|
|
673
674
|
}
|
|
674
675
|
|
|
675
|
-
return new this.ClassConstructor(...
|
|
676
|
+
return new this.ClassConstructor(...arguments_);
|
|
676
677
|
}
|
|
677
678
|
|
|
678
|
-
private calculateArgumentsHash(...
|
|
679
|
+
private calculateArgumentsHash(...arguments_: any[]): string {
|
|
679
680
|
// Calculate hash.
|
|
680
681
|
return 'hash';
|
|
681
682
|
}
|
|
@@ -747,17 +748,17 @@ There are many advanced types most users don't know about.
|
|
|
747
748
|
const instanceCounter: Map<Function, number> = new Map();
|
|
748
749
|
|
|
749
750
|
interface Constructor {
|
|
750
|
-
new(...
|
|
751
|
+
new(...arguments_: any[]): any;
|
|
751
752
|
}
|
|
752
753
|
|
|
753
754
|
// Keep track how many instances of `Constr` constructor have been created.
|
|
754
755
|
function getInstance<
|
|
755
756
|
Constr extends Constructor,
|
|
756
|
-
|
|
757
|
-
>(constructor: Constr, ...
|
|
757
|
+
Arguments extends ConstructorParameters<Constr>
|
|
758
|
+
>(constructor: Constr, ...arguments_: Arguments): InstanceType<Constr> {
|
|
758
759
|
let count = instanceCounter.get(constructor) || 0;
|
|
759
760
|
|
|
760
|
-
const instance = new constructor(...
|
|
761
|
+
const instance = new constructor(...arguments_);
|
|
761
762
|
|
|
762
763
|
instanceCounter.set(constructor, count + 1);
|
|
763
764
|
|
package/source/asyncify.d.ts
CHANGED
|
@@ -29,4 +29,4 @@ const getFooAsync: AsyncifiedFooGetter = (someArg) => {
|
|
|
29
29
|
|
|
30
30
|
@category Async
|
|
31
31
|
*/
|
|
32
|
-
export type Asyncify<Fn extends (...
|
|
32
|
+
export type Asyncify<Fn extends (...arguments_: any[]) => any> = SetReturnType<Fn, Promise<Awaited<ReturnType<Fn>>>>;
|
package/source/exact.d.ts
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
import type {KeysOfUnion} from './internal';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
Extract the element of an array that also works for array union.
|
|
5
|
-
|
|
6
|
-
Returns `never` if T is not an array.
|
|
7
|
-
|
|
8
|
-
It creates a type-safe way to access the element type of `unknown` type.
|
|
9
|
-
*/
|
|
10
|
-
type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
14
|
-
|
|
15
|
-
It creates a type-safe way to access the member type of `unknown` type.
|
|
16
|
-
*/
|
|
17
|
-
type ObjectValue<T, K> = K extends keyof T ? T[K] : never;
|
|
1
|
+
import type {KeysOfUnion, ArrayElement, ObjectValue} from './internal';
|
|
2
|
+
import type {Opaque} from './opaque';
|
|
18
3
|
|
|
19
4
|
/**
|
|
20
5
|
Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
|
|
@@ -35,7 +20,7 @@ This is useful for function type-guarding to reject arguments with excess proper
|
|
|
35
20
|
```
|
|
36
21
|
type OnlyAcceptName = {name: string};
|
|
37
22
|
|
|
38
|
-
function onlyAcceptName(
|
|
23
|
+
function onlyAcceptName(arguments_: OnlyAcceptName) {}
|
|
39
24
|
|
|
40
25
|
// TypeScript complains about excess properties when an object literal is provided.
|
|
41
26
|
onlyAcceptName({name: 'name', id: 1});
|
|
@@ -54,7 +39,7 @@ import {Exact} from 'type-fest';
|
|
|
54
39
|
|
|
55
40
|
type OnlyAcceptName = {name: string};
|
|
56
41
|
|
|
57
|
-
function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(
|
|
42
|
+
function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T) {}
|
|
58
43
|
|
|
59
44
|
const invalidInput = {name: 'name', id: 1};
|
|
60
45
|
onlyAcceptNameImproved(invalidInput); // Compilation error
|
|
@@ -69,5 +54,7 @@ export type Exact<ParameterType, InputType> =
|
|
|
69
54
|
ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
70
55
|
// In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray.
|
|
71
56
|
: ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
72
|
-
|
|
73
|
-
|
|
57
|
+
// For Opaque types, internal details are hidden from public, so let's leave it as is.
|
|
58
|
+
: ParameterType extends Opaque<infer OpaqueType, infer OpaqueToken> ? ParameterType
|
|
59
|
+
: ParameterType extends object ? ExactObject<ParameterType, InputType>
|
|
60
|
+
: ParameterType;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Declare locally scoped properties on `globalThis`.
|
|
3
|
+
|
|
4
|
+
When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`.
|
|
5
|
+
|
|
6
|
+
Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {GlobalThis} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type ExtraGlobals = GlobalThis & {
|
|
13
|
+
readonly GLOBAL_TOKEN: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
(globalThis as ExtraGlobals).GLOBAL_TOKEN;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
@category Type
|
|
20
|
+
*/
|
|
21
|
+
export type GlobalThis = typeof globalThis;
|
package/source/internal.d.ts
CHANGED
|
@@ -95,6 +95,22 @@ Extracts the type of an array or tuple minus the first element.
|
|
|
95
95
|
*/
|
|
96
96
|
export type ArrayTail<TArray extends UnknownArrayOrTuple> = TArray extends readonly [unknown, ...infer TTail] ? TTail : [];
|
|
97
97
|
|
|
98
|
+
/**
|
|
99
|
+
Extract the element of an array that also works for array union.
|
|
100
|
+
|
|
101
|
+
Returns `never` if T is not an array.
|
|
102
|
+
|
|
103
|
+
It creates a type-safe way to access the element type of `unknown` type.
|
|
104
|
+
*/
|
|
105
|
+
export type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
109
|
+
|
|
110
|
+
It creates a type-safe way to access the member type of `unknown` type.
|
|
111
|
+
*/
|
|
112
|
+
export type ObjectValue<T, K> = K extends keyof T ? T[K] : never;
|
|
113
|
+
|
|
98
114
|
/**
|
|
99
115
|
Returns a boolean for whether the string is lowercased.
|
|
100
116
|
*/
|
|
@@ -117,6 +133,16 @@ Returns a boolean for whether the the type is `any`.
|
|
|
117
133
|
*/
|
|
118
134
|
export type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
119
135
|
|
|
136
|
+
/**
|
|
137
|
+
Returns a boolean for whether the the type is `never`.
|
|
138
|
+
*/
|
|
139
|
+
export type IsNever<T> = [T] extends [never] ? true : false;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
Returns a boolean for whether the the type is `unknown`.
|
|
143
|
+
*/
|
|
144
|
+
export type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
|
|
145
|
+
|
|
120
146
|
/**
|
|
121
147
|
For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead.
|
|
122
148
|
|
|
@@ -149,7 +175,7 @@ type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
|
|
|
149
175
|
? never
|
|
150
176
|
: Type[Key] extends symbol
|
|
151
177
|
? never
|
|
152
|
-
: [(...
|
|
178
|
+
: [(...arguments_: any[]) => any] extends [Type[Key]]
|
|
153
179
|
? never
|
|
154
180
|
: Key;
|
|
155
181
|
|
package/source/jsonify.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {NegativeInfinity, PositiveInfinity} from './numeric';
|
|
|
5
5
|
import type {TypedArray} from './typed-array';
|
|
6
6
|
|
|
7
7
|
// Note: The return value has to be `any` and not `unknown` so it can match `void`.
|
|
8
|
-
type NotJsonable = ((...
|
|
8
|
+
type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol;
|
|
9
9
|
|
|
10
10
|
type JsonifyTuple<T extends [unknown, ...unknown[]]> = {
|
|
11
11
|
[Key in keyof T]: T[Key] extends NotJsonable ? null : Jsonify<T[Key]>;
|
|
@@ -35,7 +35,7 @@ An interface cannot be structurally compared to `JsonValue` because an interface
|
|
|
35
35
|
|
|
36
36
|
@example
|
|
37
37
|
```
|
|
38
|
-
import type {Jsonify} from 'type-fest';
|
|
38
|
+
import type {Jsonify, JsonValue} from 'type-fest';
|
|
39
39
|
|
|
40
40
|
interface Geometry {
|
|
41
41
|
type: 'Point' | 'Polygon';
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
4
|
-
type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
|
|
1
|
+
import type {IsUnknown} from './internal';
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
4
|
Create a function type with a return type of your choice and the same parameters as the given function type.
|
|
@@ -20,13 +17,13 @@ type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | u
|
|
|
20
17
|
|
|
21
18
|
@category Function
|
|
22
19
|
*/
|
|
23
|
-
export type SetReturnType<Fn extends (...
|
|
20
|
+
export type SetReturnType<Fn extends (...arguments_: any[]) => any, TypeToReturn> =
|
|
24
21
|
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
|
|
25
|
-
Fn extends (this: infer ThisArg, ...
|
|
22
|
+
Fn extends (this: infer ThisArg, ...arguments_: infer Arguments) => any ? (
|
|
26
23
|
// If a function did not specify the `this` fake parameter, it will be inferred to `unknown`.
|
|
27
24
|
// We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE.
|
|
28
|
-
IsUnknown<ThisArg> extends true ? (...
|
|
25
|
+
IsUnknown<ThisArg> extends true ? (...arguments_: Arguments) => TypeToReturn : (this: ThisArg, ...arguments_: Arguments) => TypeToReturn
|
|
29
26
|
) : (
|
|
30
27
|
// This part should be unreachable, but we make it meaningful just in case…
|
|
31
|
-
(...
|
|
28
|
+
(...arguments_: Parameters<Fn>) => TypeToReturn
|
|
32
29
|
);
|