type-fest 2.6.0 → 2.10.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 +15 -0
- package/package.json +1 -1
- package/readme.md +66 -36
- package/source/async-return-type.d.ts +1 -1
- package/source/asyncify.d.ts +1 -1
- package/source/basic.d.ts +6 -6
- package/source/camel-case.d.ts +2 -1
- package/source/camel-cased-properties-deep.d.ts +3 -1
- package/source/camel-cased-properties.d.ts +3 -1
- package/source/conditional-except.d.ts +1 -1
- package/source/conditional-keys.d.ts +1 -1
- package/source/conditional-pick.d.ts +1 -1
- package/source/delimiter-case.d.ts +3 -2
- package/source/delimiter-cased-properties-deep.d.ts +4 -2
- package/source/delimiter-cased-properties.d.ts +3 -1
- package/source/entries.d.ts +4 -1
- package/source/entry.d.ts +4 -1
- package/source/except.d.ts +1 -1
- package/source/fixed-length-array.d.ts +1 -1
- package/source/get.d.ts +56 -12
- package/source/includes.d.ts +1 -1
- package/source/internal.d.ts +7 -0
- package/source/iterable-element.d.ts +1 -1
- package/source/join.d.ts +2 -1
- package/source/jsonify.d.ts +2 -2
- package/source/kebab-case.d.ts +2 -1
- package/source/kebab-cased-properties-deep.d.ts +3 -1
- package/source/kebab-cased-properties.d.ts +3 -1
- package/source/last-array-element.d.ts +2 -1
- package/source/literal-to-primitive.d.ts +36 -0
- package/source/literal-union.d.ts +3 -3
- package/source/merge-exclusive.d.ts +1 -1
- package/source/merge.d.ts +1 -1
- package/source/multidimensional-array.d.ts +1 -1
- package/source/multidimensional-readonly-array.d.ts +1 -1
- package/source/mutable.d.ts +1 -1
- package/source/numeric.d.ts +168 -0
- package/source/observable-like.d.ts +15 -1
- package/source/opaque.d.ts +1 -1
- package/source/package-json.d.ts +1 -1
- package/source/partial-deep.d.ts +7 -4
- package/source/pascal-case.d.ts +2 -1
- package/source/pascal-cased-properties-deep.d.ts +4 -2
- package/source/pascal-cased-properties.d.ts +3 -1
- package/source/primitive.d.ts +1 -1
- package/source/promisable.d.ts +2 -2
- package/source/promise-value.d.ts +1 -1
- package/source/readonly-deep.d.ts +6 -3
- package/source/remove-index-signature.d.ts +98 -0
- package/source/require-all-or-none.d.ts +1 -1
- package/source/require-at-least-one.d.ts +1 -1
- package/source/require-exactly-one.d.ts +1 -1
- package/source/screaming-snake-case.d.ts +2 -1
- package/source/set-optional.d.ts +1 -1
- package/source/set-required.d.ts +1 -1
- package/source/set-return-type.d.ts +1 -1
- package/source/simplify.d.ts +1 -1
- package/source/snake-case.d.ts +2 -1
- package/source/snake-cased-properties-deep.d.ts +3 -1
- package/source/snake-cased-properties.d.ts +3 -1
- package/source/split.d.ts +2 -1
- package/source/string-key-of.d.ts +25 -0
- package/source/stringified.d.ts +1 -1
- package/source/trim.d.ts +2 -1
- package/source/tsconfig-json.d.ts +1 -1
- package/source/typed-array.d.ts +1 -1
- package/source/union-to-intersection.d.ts +1 -1
- package/source/value-of.d.ts +1 -1
|
@@ -38,6 +38,8 @@ const result: KebabCasedPropertiesDeep<UserWithFriends> = {
|
|
|
38
38
|
};
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
@category
|
|
41
|
+
@category Change case
|
|
42
|
+
@category Template literal
|
|
43
|
+
@category Object
|
|
42
44
|
*/
|
|
43
45
|
export type KebabCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '-'>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the {@link Primitive | primitive type} it belongs to, or `never` if it's not a primitive.
|
|
3
|
+
|
|
4
|
+
Use-case: Working with generic types that may be literal types.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import {LiteralToPrimitive} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
// No overloads needed to get the correct return type
|
|
11
|
+
function plus<T extends number | bigint | string>(x: T, y: T): LiteralToPrimitive<T> {
|
|
12
|
+
return x + (y as any);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
plus('a', 'b'); // string
|
|
16
|
+
plus(1, 2); // number
|
|
17
|
+
plus(1n, 2n); // bigint
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
@category Type
|
|
21
|
+
*/
|
|
22
|
+
export type LiteralToPrimitive<T> = T extends number
|
|
23
|
+
? number
|
|
24
|
+
: T extends bigint
|
|
25
|
+
? bigint
|
|
26
|
+
: T extends string
|
|
27
|
+
? string
|
|
28
|
+
: T extends boolean
|
|
29
|
+
? boolean
|
|
30
|
+
: T extends symbol
|
|
31
|
+
? symbol
|
|
32
|
+
: T extends null
|
|
33
|
+
? null
|
|
34
|
+
: T extends undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: never;
|
|
@@ -27,9 +27,9 @@ const pet: Pet2 = '';
|
|
|
27
27
|
// You **will** get auto-completion for `dog` and `cat` literals.
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
@category
|
|
31
|
-
|
|
30
|
+
@category Type
|
|
31
|
+
*/
|
|
32
32
|
export type LiteralUnion<
|
|
33
33
|
LiteralType,
|
|
34
34
|
BaseType extends Primitive,
|
|
35
|
-
> = LiteralType | (BaseType &
|
|
35
|
+
> = LiteralType | (BaseType & Record<never, never>);
|
package/source/merge.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ const matrix = emptyMatrix(3);
|
|
|
38
38
|
const answer = matrix[0][0][0]; // 42
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
@category
|
|
41
|
+
@category Array
|
|
42
42
|
*/
|
|
43
43
|
export type MultidimensionalReadonlyArray<Element, Dimensions extends number> = number extends Dimensions
|
|
44
44
|
? Recursive<Element>
|
package/source/mutable.d.ts
CHANGED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
type Numeric = number | bigint;
|
|
2
|
+
|
|
3
|
+
type Zero = 0 | 0n;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Matches the hidden `Infinity` type.
|
|
7
|
+
|
|
8
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
|
|
9
|
+
|
|
10
|
+
@see NegativeInfinity
|
|
11
|
+
|
|
12
|
+
@category Numeric
|
|
13
|
+
*/
|
|
14
|
+
// See https://github.com/microsoft/TypeScript/issues/31752
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
|
|
16
|
+
export type PositiveInfinity = 1e999;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
Matches the hidden `-Infinity` type.
|
|
20
|
+
|
|
21
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
|
|
22
|
+
|
|
23
|
+
@see PositiveInfinity
|
|
24
|
+
|
|
25
|
+
@category Numeric
|
|
26
|
+
*/
|
|
27
|
+
// See https://github.com/microsoft/TypeScript/issues/31752
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
|
|
29
|
+
export type NegativeInfinity = -1e999;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
A finite `number`.
|
|
33
|
+
You can't pass a `bigint` as they are already guaranteed to be finite.
|
|
34
|
+
|
|
35
|
+
Use-case: Validating and documenting parameters.
|
|
36
|
+
|
|
37
|
+
@example
|
|
38
|
+
```
|
|
39
|
+
import {Finite} from 'type-fest';
|
|
40
|
+
|
|
41
|
+
declare function setScore<T extends number>(length: Finite<T>): void;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
@category Numeric
|
|
45
|
+
*/
|
|
46
|
+
export type Finite<T extends number> = T extends PositiveInfinity | NegativeInfinity ? never : T;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
A `number` that is an integer.
|
|
50
|
+
You can't pass a `bigint` as they are already guaranteed to be integers.
|
|
51
|
+
|
|
52
|
+
Use-case: Validating and documenting parameters.
|
|
53
|
+
|
|
54
|
+
@example
|
|
55
|
+
```
|
|
56
|
+
import {Integer} from 'type-fest';
|
|
57
|
+
|
|
58
|
+
declare function setYear<T extends number>(length: Integer<T>): void;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
@see NegativeInteger
|
|
62
|
+
@see NonNegativeInteger
|
|
63
|
+
|
|
64
|
+
@category Numeric
|
|
65
|
+
*/
|
|
66
|
+
// `${bigint}` is a type that matches a valid bigint literal without the `n` (ex. 1, 0b1, 0o1, 0x1)
|
|
67
|
+
// Because T is a number and not a string we can effectively use this to filter out any numbers containing decimal points
|
|
68
|
+
export type Integer<T extends number> = `${T}` extends `${bigint}` ? T : never;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
A `number` that is not an integer.
|
|
72
|
+
You can't pass a `bigint` as they are already guaranteed to be integers.
|
|
73
|
+
|
|
74
|
+
Use-case: Validating and documenting parameters.
|
|
75
|
+
|
|
76
|
+
@example
|
|
77
|
+
```
|
|
78
|
+
import {Float} from 'type-fest';
|
|
79
|
+
|
|
80
|
+
declare function setPercentage<T extends number>(length: Float<T>): void;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
@see Integer
|
|
84
|
+
|
|
85
|
+
@category Numeric
|
|
86
|
+
*/
|
|
87
|
+
export type Float<T extends number> = T extends Integer<T> ? never : T;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
A negative (`-∞ < x < 0`) `number` that is not an integer.
|
|
91
|
+
Equivalent to `Negative<Float<T>>`.
|
|
92
|
+
|
|
93
|
+
Use-case: Validating and documenting parameters.
|
|
94
|
+
|
|
95
|
+
@see Negative
|
|
96
|
+
@see Float
|
|
97
|
+
|
|
98
|
+
@category Numeric
|
|
99
|
+
*/
|
|
100
|
+
export type NegativeFloat<T extends number> = Negative<Float<T>>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
A negative `number`/`bigint` (`-∞ < x < 0`)
|
|
104
|
+
|
|
105
|
+
Use-case: Validating and documenting parameters.
|
|
106
|
+
|
|
107
|
+
@see NegativeInteger
|
|
108
|
+
@see NonNegative
|
|
109
|
+
|
|
110
|
+
@category Numeric
|
|
111
|
+
*/
|
|
112
|
+
export type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
A negative (`-∞ < x < 0`) `number` that is an integer.
|
|
116
|
+
Equivalent to `Negative<Integer<T>>`.
|
|
117
|
+
|
|
118
|
+
You can't pass a `bigint` as they are already guaranteed to be integers, instead use `Negative<T>`.
|
|
119
|
+
|
|
120
|
+
Use-case: Validating and documenting parameters.
|
|
121
|
+
|
|
122
|
+
@see Negative
|
|
123
|
+
@see Integer
|
|
124
|
+
|
|
125
|
+
@category Numeric
|
|
126
|
+
*/
|
|
127
|
+
export type NegativeInteger<T extends number> = Negative<Integer<T>>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
A non-negative `number`/`bigint` (`0 <= x < ∞`).
|
|
131
|
+
|
|
132
|
+
Use-case: Validating and documenting parameters.
|
|
133
|
+
|
|
134
|
+
@see NonNegativeInteger
|
|
135
|
+
@see Negative
|
|
136
|
+
|
|
137
|
+
@example
|
|
138
|
+
```
|
|
139
|
+
import {NonNegative} from 'type-fest';
|
|
140
|
+
|
|
141
|
+
declare function setLength<T extends number>(length: NonNegative<T>): void;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
@category Numeric
|
|
145
|
+
*/
|
|
146
|
+
export type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : never;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
A non-negative (`0 <= x < ∞`) `number` that is an integer.
|
|
150
|
+
Equivalent to `NonNegative<Integer<T>>`.
|
|
151
|
+
|
|
152
|
+
You can't pass a `bigint` as they are already guaranteed to be integers, instead use `NonNegative<T>`.
|
|
153
|
+
|
|
154
|
+
Use-case: Validating and documenting parameters.
|
|
155
|
+
|
|
156
|
+
@see NonNegative
|
|
157
|
+
@see Integer
|
|
158
|
+
|
|
159
|
+
@example
|
|
160
|
+
```
|
|
161
|
+
import {NonNegativeInteger} from 'type-fest';
|
|
162
|
+
|
|
163
|
+
declare function setLength<T extends number>(length: NonNegativeInteger<T>): void;
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
@category Numeric
|
|
167
|
+
*/
|
|
168
|
+
export type NonNegativeInteger<T extends number> = NonNegative<Integer<T>>;
|
|
@@ -11,15 +11,29 @@ As well, some guideance on making an `Observable` do not include `closed` proper
|
|
|
11
11
|
@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
|
|
12
12
|
@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
|
|
13
13
|
@see https://github.com/benlesh/symbol-observable#making-an-object-observable
|
|
14
|
+
|
|
15
|
+
@category Observable
|
|
14
16
|
*/
|
|
15
17
|
export type Unsubscribable = {
|
|
16
18
|
unsubscribe(): void;
|
|
17
19
|
};
|
|
18
20
|
|
|
21
|
+
/**
|
|
22
|
+
@category Observable
|
|
23
|
+
*/
|
|
19
24
|
type OnNext<ValueType> = (value: ValueType) => void;
|
|
25
|
+
/**
|
|
26
|
+
@category Observable
|
|
27
|
+
*/
|
|
20
28
|
type OnError = (error: unknown) => void;
|
|
29
|
+
/**
|
|
30
|
+
@category Observable
|
|
31
|
+
*/
|
|
21
32
|
type OnComplete = () => void;
|
|
22
33
|
|
|
34
|
+
/**
|
|
35
|
+
@category Observable
|
|
36
|
+
*/
|
|
23
37
|
export type Observer<ValueType> = {
|
|
24
38
|
next: OnNext<ValueType>;
|
|
25
39
|
error: OnError;
|
|
@@ -40,7 +54,7 @@ But `Observable` implementations have evolved to preferring case 2 and some impl
|
|
|
40
54
|
@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L246-L259
|
|
41
55
|
@see https://benlesh.com/posts/learning-observable-by-building-observable/
|
|
42
56
|
|
|
43
|
-
@category
|
|
57
|
+
@category Observable
|
|
44
58
|
*/
|
|
45
59
|
export interface ObservableLike<ValueType = unknown> {
|
|
46
60
|
subscribe(observer?: Partial<Observer<ValueType>>): Unsubscribable;
|
package/source/opaque.d.ts
CHANGED
package/source/package-json.d.ts
CHANGED
|
@@ -635,7 +635,7 @@ declare namespace PackageJson {
|
|
|
635
635
|
/**
|
|
636
636
|
Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn.
|
|
637
637
|
|
|
638
|
-
@category
|
|
638
|
+
@category File
|
|
639
639
|
*/
|
|
640
640
|
export type PackageJson =
|
|
641
641
|
PackageJson.PackageJsonStandard &
|
package/source/partial-deep.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {BuiltIns} from './internal';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
Create a type from another type with all keys and nested keys set to optional.
|
|
@@ -28,10 +28,13 @@ const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
|
|
|
28
28
|
settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
@category
|
|
31
|
+
@category Object
|
|
32
|
+
@category Array
|
|
33
|
+
@category Set
|
|
34
|
+
@category Map
|
|
32
35
|
*/
|
|
33
|
-
export type PartialDeep<T> = T extends
|
|
34
|
-
?
|
|
36
|
+
export type PartialDeep<T> = T extends BuiltIns
|
|
37
|
+
? T
|
|
35
38
|
: T extends Map<infer KeyType, infer ValueType>
|
|
36
39
|
? PartialMapDeep<KeyType, ValueType>
|
|
37
40
|
: T extends Set<infer ItemType>
|
package/source/pascal-case.d.ts
CHANGED
|
@@ -30,7 +30,8 @@ const dbResult: CamelCasedProperties<ModelProps> = {
|
|
|
30
30
|
};
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
@category
|
|
33
|
+
@category Change case
|
|
34
|
+
@category Template literal
|
|
34
35
|
*/
|
|
35
36
|
export type PascalCase<Value> = CamelCase<Value> extends string
|
|
36
37
|
? Capitalize<CamelCase<Value>>
|
|
@@ -38,9 +38,11 @@ const result: PascalCasedPropertiesDeep<UserWithFriends> = {
|
|
|
38
38
|
};
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
@category
|
|
41
|
+
@category Change case
|
|
42
|
+
@category Template literal
|
|
43
|
+
@category Object
|
|
42
44
|
*/
|
|
43
|
-
export type PascalCasedPropertiesDeep<Value> = Value extends Function
|
|
45
|
+
export type PascalCasedPropertiesDeep<Value> = Value extends Function | Date | RegExp
|
|
44
46
|
? Value
|
|
45
47
|
: Value extends Array<infer U>
|
|
46
48
|
? Array<PascalCasedPropertiesDeep<U>>
|
package/source/primitive.d.ts
CHANGED
package/source/promisable.d.ts
CHANGED
|
@@ -18,8 +18,8 @@ async function logger(getLogEntry: () => Promisable<string>): Promise<void> {
|
|
|
18
18
|
|
|
19
19
|
logger(() => 'foo');
|
|
20
20
|
logger(() => Promise.resolve('bar'));
|
|
21
|
-
|
|
22
|
-
@category Utilities
|
|
23
21
|
```
|
|
22
|
+
|
|
23
|
+
@category Async
|
|
24
24
|
*/
|
|
25
25
|
export type Promisable<T> = T | PromiseLike<T>;
|
|
@@ -24,6 +24,6 @@ type RecursiveAsyncData = Promise<Promise<string> >;
|
|
|
24
24
|
let recursiveAsyncData: PromiseValue<RecursiveAsyncData> = Promise.resolve(Promise.resolve('ABC'));
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
@category
|
|
27
|
+
@category Async
|
|
28
28
|
*/
|
|
29
29
|
export type PromiseValue<PromiseType> = PromiseType extends PromiseLike<infer Value> ? PromiseValue<Value> : PromiseType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {BuiltIns} from './internal';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively.
|
|
@@ -29,9 +29,12 @@ data.foo.push('bar');
|
|
|
29
29
|
//=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
@category
|
|
32
|
+
@category Object
|
|
33
|
+
@category Array
|
|
34
|
+
@category Set
|
|
35
|
+
@category Map
|
|
33
36
|
*/
|
|
34
|
-
export type ReadonlyDeep<T> = T extends
|
|
37
|
+
export type ReadonlyDeep<T> = T extends BuiltIns | ((...arguments: any[]) => unknown)
|
|
35
38
|
? T
|
|
36
39
|
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
37
40
|
? ReadonlyMapDeep<KeyType, ValueType>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Remove any index signatures from the given object type, so that only explicitly defined properties remain.
|
|
3
|
+
|
|
4
|
+
Use-cases:
|
|
5
|
+
- Remove overly permissive signatures from third-party types.
|
|
6
|
+
|
|
7
|
+
This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
|
|
8
|
+
|
|
9
|
+
It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`.
|
|
10
|
+
|
|
11
|
+
(The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
const indexed: Record<string, unknown> = {}; // Allowed
|
|
15
|
+
|
|
16
|
+
const keyed: Record<'foo', unknown> = {}; // Error
|
|
17
|
+
// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
type Indexed = {} extends Record<string, unknown>
|
|
24
|
+
? '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
25
|
+
: '❌ `{}` is NOT assignable to `Record<string, unknown>`';
|
|
26
|
+
// => '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
27
|
+
|
|
28
|
+
type Keyed = {} extends Record<'foo' | 'bar', unknown>
|
|
29
|
+
? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
|
|
30
|
+
: "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
|
|
31
|
+
// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
38
|
+
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
39
|
+
]: ObjectType[KeyType]; // ...to its original value, i.e. `RemoveIndexSignature<Foo> == Foo`.
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
47
|
+
[KeyType in keyof ObjectType
|
|
48
|
+
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
49
|
+
as {} extends Record<KeyType, unknown>
|
|
50
|
+
? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
|
|
51
|
+
: ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
|
|
52
|
+
]: ObjectType[KeyType];
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
type RemoveIndexSignature<ObjectType> = {
|
|
60
|
+
[KeyType in keyof ObjectType
|
|
61
|
+
as {} extends Record<KeyType, unknown>
|
|
62
|
+
? never // => Remove this `KeyType`.
|
|
63
|
+
: KeyType // => Keep this `KeyType` as it is.
|
|
64
|
+
]: ObjectType[KeyType];
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
@example
|
|
69
|
+
```
|
|
70
|
+
import {RemoveIndexSignature} from 'type-fest';
|
|
71
|
+
|
|
72
|
+
interface Example {
|
|
73
|
+
// These index signatures will be removed.
|
|
74
|
+
[x: string]: any
|
|
75
|
+
[x: number]: any
|
|
76
|
+
[x: symbol]: any
|
|
77
|
+
[x: `head-${string}`]: string
|
|
78
|
+
[x: `${string}-tail`]: string
|
|
79
|
+
[x: `head-${string}-tail`]: string
|
|
80
|
+
[x: `${bigint}`]: string
|
|
81
|
+
[x: `embedded-${number}`]: string
|
|
82
|
+
|
|
83
|
+
// These explicitly defined keys will remain.
|
|
84
|
+
foo: 'bar';
|
|
85
|
+
qux?: 'baz';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type ExampleWithoutIndexSignatures = RemoveIndexSignature<Example>;
|
|
89
|
+
// => { foo: 'bar'; qux?: 'baz' | undefined; }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
@category Object
|
|
93
|
+
*/
|
|
94
|
+
export type RemoveIndexSignature<ObjectType> = {
|
|
95
|
+
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
96
|
+
? never
|
|
97
|
+
: KeyType]: ObjectType[KeyType];
|
|
98
|
+
};
|
|
@@ -27,7 +27,7 @@ const responder2: RequireAllOrNone<Responder, 'text' | 'json'> = {
|
|
|
27
27
|
};
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
@category
|
|
30
|
+
@category Object
|
|
31
31
|
*/
|
|
32
32
|
export type RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType = never> = (
|
|
33
33
|
| Required<Pick<ObjectType, KeysType>> // Require all of the given keys.
|
|
@@ -23,7 +23,8 @@ import {ScreamingSnakeCase} from 'type-fest';
|
|
|
23
23
|
const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
@category
|
|
26
|
+
@category Change case
|
|
27
|
+
@category Template literal
|
|
27
28
|
*/
|
|
28
29
|
export type ScreamingSnakeCase<Value> = Value extends string
|
|
29
30
|
? IsScreamingSnakeCase<Value> extends true
|
package/source/set-optional.d.ts
CHANGED
package/source/set-required.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | u
|
|
|
17
17
|
//=> type MyWrappedFunction = (foo: SomeType, bar: unknown) => SomeOtherType | undefined;
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
@category
|
|
20
|
+
@category Function
|
|
21
21
|
*/
|
|
22
22
|
export type SetReturnType<Fn extends (...args: any[]) => any, TypeToReturn> =
|
|
23
23
|
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
|
package/source/simplify.d.ts
CHANGED