@depup/type-fest 5.4.4-depup.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/README.md +25 -0
- package/index.d.ts +211 -0
- package/license-cc0 +121 -0
- package/license-mit +9 -0
- package/package.json +85 -0
- package/readme.md +1052 -0
- package/source/all-extend.d.ts +120 -0
- package/source/all-union-fields.d.ts +91 -0
- package/source/and.d.ts +81 -0
- package/source/array-element.d.ts +46 -0
- package/source/array-indices.d.ts +25 -0
- package/source/array-reverse.d.ts +84 -0
- package/source/array-slice.d.ts +132 -0
- package/source/array-splice.d.ts +104 -0
- package/source/array-tail.d.ts +70 -0
- package/source/array-values.d.ts +24 -0
- package/source/arrayable.d.ts +31 -0
- package/source/async-return-type.d.ts +28 -0
- package/source/asyncify.d.ts +25 -0
- package/source/basic.d.ts +38 -0
- package/source/camel-case.d.ts +92 -0
- package/source/camel-cased-properties-deep.d.ts +99 -0
- package/source/camel-cased-properties.d.ts +45 -0
- package/source/characters.d.ts +67 -0
- package/source/conditional-except.d.ts +47 -0
- package/source/conditional-keys.d.ts +63 -0
- package/source/conditional-pick-deep.d.ts +120 -0
- package/source/conditional-pick.d.ts +46 -0
- package/source/conditional-simplify-deep.d.ts +73 -0
- package/source/conditional-simplify.d.ts +50 -0
- package/source/delimiter-case.d.ts +77 -0
- package/source/delimiter-cased-properties-deep.d.ts +108 -0
- package/source/delimiter-cased-properties.d.ts +48 -0
- package/source/distributed-omit.d.ts +96 -0
- package/source/distributed-pick.d.ts +92 -0
- package/source/empty-object.d.ts +51 -0
- package/source/entries.d.ts +64 -0
- package/source/entry.d.ts +67 -0
- package/source/exact.d.ts +73 -0
- package/source/except.d.ts +112 -0
- package/source/exclude-rest-element.d.ts +40 -0
- package/source/exclude-strict.d.ts +51 -0
- package/source/exclusify-union.d.ts +147 -0
- package/source/extends-strict.d.ts +44 -0
- package/source/extract-rest-element.d.ts +30 -0
- package/source/extract-strict.d.ts +51 -0
- package/source/find-global-type.d.ts +68 -0
- package/source/fixed-length-array.d.ts +97 -0
- package/source/get.d.ts +227 -0
- package/source/global-this.d.ts +24 -0
- package/source/globals/index.d.ts +3 -0
- package/source/globals/observable-like.d.ts +78 -0
- package/source/greater-than-or-equal.d.ts +30 -0
- package/source/greater-than.d.ts +58 -0
- package/source/has-optional-keys.d.ts +23 -0
- package/source/has-readonly-keys.d.ts +23 -0
- package/source/has-required-keys.d.ts +61 -0
- package/source/has-writable-keys.d.ts +23 -0
- package/source/if-any.d.ts +28 -0
- package/source/if-empty-object.d.ts +30 -0
- package/source/if-never.d.ts +28 -0
- package/source/if-null.d.ts +28 -0
- package/source/if-unknown.d.ts +28 -0
- package/source/if.d.ts +102 -0
- package/source/includes.d.ts +24 -0
- package/source/int-closed-range.d.ts +47 -0
- package/source/int-range.d.ts +69 -0
- package/source/internal/array.d.ts +151 -0
- package/source/internal/characters.d.ts +65 -0
- package/source/internal/enforce-optional.d.ts +49 -0
- package/source/internal/index.d.ts +11 -0
- package/source/internal/keys.d.ts +100 -0
- package/source/internal/numeric.d.ts +151 -0
- package/source/internal/object.d.ts +292 -0
- package/source/internal/string.d.ts +202 -0
- package/source/internal/tuple.d.ts +79 -0
- package/source/internal/type.d.ts +164 -0
- package/source/invariant-of.d.ts +85 -0
- package/source/is-any.d.ts +31 -0
- package/source/is-equal.d.ts +42 -0
- package/source/is-float.d.ts +43 -0
- package/source/is-integer.d.ts +60 -0
- package/source/is-literal.d.ts +315 -0
- package/source/is-lowercase.d.ts +38 -0
- package/source/is-never.d.ts +56 -0
- package/source/is-null.d.ts +22 -0
- package/source/is-nullable.d.ts +30 -0
- package/source/is-optional-key-of.d.ts +51 -0
- package/source/is-optional.d.ts +28 -0
- package/source/is-readonly-key-of.d.ts +55 -0
- package/source/is-required-key-of.d.ts +51 -0
- package/source/is-tuple.d.ts +92 -0
- package/source/is-undefined.d.ts +22 -0
- package/source/is-union.d.ts +40 -0
- package/source/is-unknown.d.ts +43 -0
- package/source/is-uppercase.d.ts +38 -0
- package/source/is-writable-key-of.d.ts +51 -0
- package/source/iterable-element.d.ts +66 -0
- package/source/join.d.ts +79 -0
- package/source/json-value.d.ts +33 -0
- package/source/jsonifiable.d.ts +37 -0
- package/source/jsonify.d.ts +127 -0
- package/source/kebab-case.d.ts +46 -0
- package/source/kebab-cased-properties-deep.d.ts +65 -0
- package/source/kebab-cased-properties.d.ts +42 -0
- package/source/key-as-string.d.ts +27 -0
- package/source/keys-of-union.d.ts +44 -0
- package/source/last-array-element.d.ts +36 -0
- package/source/less-than-or-equal.d.ts +24 -0
- package/source/less-than.d.ts +28 -0
- package/source/literal-to-primitive-deep.d.ts +71 -0
- package/source/literal-to-primitive.d.ts +38 -0
- package/source/literal-union.d.ts +39 -0
- package/source/merge-deep.d.ts +495 -0
- package/source/merge-exclusive.d.ts +45 -0
- package/source/merge.d.ts +62 -0
- package/source/multidimensional-array.d.ts +38 -0
- package/source/multidimensional-readonly-array.d.ts +38 -0
- package/source/non-empty-object.d.ts +38 -0
- package/source/non-empty-string.d.ts +32 -0
- package/source/non-empty-tuple.d.ts +24 -0
- package/source/numeric.d.ts +226 -0
- package/source/object-merge.d.ts +194 -0
- package/source/omit-deep.d.ts +154 -0
- package/source/omit-index-signature.d.ts +98 -0
- package/source/opaque.d.ts +3 -0
- package/source/optional-keys-of.d.ts +46 -0
- package/source/or.d.ts +89 -0
- package/source/override-properties.d.ts +43 -0
- package/source/package-json.d.ts +710 -0
- package/source/partial-deep.d.ts +155 -0
- package/source/partial-on-undefined-deep.d.ts +81 -0
- package/source/pascal-case.d.ts +51 -0
- package/source/pascal-cased-properties-deep.d.ts +72 -0
- package/source/pascal-cased-properties.d.ts +42 -0
- package/source/paths.d.ts +241 -0
- package/source/pick-deep.d.ts +152 -0
- package/source/pick-index-signature.d.ts +52 -0
- package/source/primitive.d.ts +15 -0
- package/source/promisable.d.ts +27 -0
- package/source/readonly-deep.d.ts +116 -0
- package/source/readonly-keys-of.d.ts +38 -0
- package/source/readonly-tuple.d.ts +34 -0
- package/source/remove-prefix.d.ts +132 -0
- package/source/replace.d.ts +87 -0
- package/source/require-all-or-none.d.ts +54 -0
- package/source/require-at-least-one.d.ts +50 -0
- package/source/require-exactly-one.d.ts +48 -0
- package/source/require-one-or-none.d.ts +49 -0
- package/source/required-deep.d.ts +76 -0
- package/source/required-keys-of.d.ts +38 -0
- package/source/schema.d.ts +119 -0
- package/source/screaming-snake-case.d.ts +30 -0
- package/source/set-field-type.d.ts +67 -0
- package/source/set-non-nullable-deep.d.ts +85 -0
- package/source/set-non-nullable.d.ts +41 -0
- package/source/set-optional.d.ts +46 -0
- package/source/set-parameter-type.d.ts +125 -0
- package/source/set-readonly.d.ts +44 -0
- package/source/set-required-deep.d.ts +64 -0
- package/source/set-required.d.ts +79 -0
- package/source/set-return-type.d.ts +31 -0
- package/source/shared-union-fields-deep.d.ts +180 -0
- package/source/shared-union-fields.d.ts +79 -0
- package/source/simplify-deep.d.ts +117 -0
- package/source/simplify.d.ts +61 -0
- package/source/single-key-object.d.ts +28 -0
- package/source/snake-case.d.ts +47 -0
- package/source/snake-cased-properties-deep.d.ts +65 -0
- package/source/snake-cased-properties.d.ts +42 -0
- package/source/split-on-rest-element.d.ts +106 -0
- package/source/split.d.ts +90 -0
- package/source/spread.d.ts +82 -0
- package/source/string-repeat.d.ts +49 -0
- package/source/string-slice.d.ts +39 -0
- package/source/stringified.d.ts +25 -0
- package/source/structured-cloneable.d.ts +89 -0
- package/source/subtract.d.ts +86 -0
- package/source/sum.d.ts +81 -0
- package/source/tagged-union.d.ts +53 -0
- package/source/tagged.d.ts +263 -0
- package/source/trim.d.ts +29 -0
- package/source/tsconfig-json.d.ts +1324 -0
- package/source/tuple-of.d.ts +80 -0
- package/source/tuple-to-object.d.ts +47 -0
- package/source/tuple-to-union.d.ts +54 -0
- package/source/typed-array.d.ts +19 -0
- package/source/undefined-on-partial-deep.d.ts +83 -0
- package/source/union-to-intersection.d.ts +35 -0
- package/source/union-to-tuple.d.ts +58 -0
- package/source/unknown-array.d.ts +27 -0
- package/source/unknown-map.d.ts +26 -0
- package/source/unknown-record.d.ts +33 -0
- package/source/unknown-set.d.ts +26 -0
- package/source/unwrap-partial.d.ts +33 -0
- package/source/value-of.d.ts +24 -0
- package/source/words.d.ts +122 -0
- package/source/writable-deep.d.ts +84 -0
- package/source/writable-keys-of.d.ts +34 -0
- package/source/writable.d.ts +72 -0
- package/source/xor.d.ts +83 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type {TupleOf} from './tuple-of.d.ts';
|
|
2
|
+
import type {BuildObject, NonRecursiveType, ObjectValue} from './internal/index.d.ts';
|
|
3
|
+
import type {IsNever} from './is-never.d.ts';
|
|
4
|
+
import type {Paths} from './paths.d.ts';
|
|
5
|
+
import type {Simplify} from './simplify.d.ts';
|
|
6
|
+
import type {UnionToIntersection} from './union-to-intersection.d.ts';
|
|
7
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Pick properties from a deeply-nested object.
|
|
11
|
+
|
|
12
|
+
It supports recursing into arrays.
|
|
13
|
+
|
|
14
|
+
Use-case: Distill complex objects down to the components you need to target.
|
|
15
|
+
|
|
16
|
+
@example
|
|
17
|
+
```
|
|
18
|
+
import type {PickDeep, PartialDeep} from 'type-fest';
|
|
19
|
+
|
|
20
|
+
type Configuration = {
|
|
21
|
+
userConfig: {
|
|
22
|
+
name: string;
|
|
23
|
+
age: number;
|
|
24
|
+
address: [
|
|
25
|
+
{
|
|
26
|
+
city1: string;
|
|
27
|
+
street1: string;
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
city2: string;
|
|
31
|
+
street2: string;
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
};
|
|
35
|
+
otherConfig: any;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type NameConfig = PickDeep<Configuration, 'userConfig.name'>;
|
|
39
|
+
// type NameConfig = {
|
|
40
|
+
// userConfig: {
|
|
41
|
+
// name: string;
|
|
42
|
+
// }
|
|
43
|
+
// };
|
|
44
|
+
|
|
45
|
+
// Supports optional properties
|
|
46
|
+
type User = PickDeep<PartialDeep<Configuration>, 'userConfig.name' | 'userConfig.age'>;
|
|
47
|
+
// type User = {
|
|
48
|
+
// userConfig?: {
|
|
49
|
+
// name?: string;
|
|
50
|
+
// age?: number;
|
|
51
|
+
// };
|
|
52
|
+
// };
|
|
53
|
+
|
|
54
|
+
// Supports array
|
|
55
|
+
type AddressConfig = PickDeep<Configuration, 'userConfig.address.0'>;
|
|
56
|
+
// type AddressConfig = {
|
|
57
|
+
// userConfig: {
|
|
58
|
+
// address: [{
|
|
59
|
+
// city1: string;
|
|
60
|
+
// street1: string;
|
|
61
|
+
// }];
|
|
62
|
+
// };
|
|
63
|
+
// }
|
|
64
|
+
|
|
65
|
+
// Supports recurse into array
|
|
66
|
+
type Street = PickDeep<Configuration, 'userConfig.address.1.street2'>;
|
|
67
|
+
// type Street = {
|
|
68
|
+
// userConfig: {
|
|
69
|
+
// address: [
|
|
70
|
+
// unknown,
|
|
71
|
+
// {street2: string}
|
|
72
|
+
// ];
|
|
73
|
+
// };
|
|
74
|
+
// }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
@category Object
|
|
78
|
+
@category Array
|
|
79
|
+
*/
|
|
80
|
+
export type PickDeep<T, PathUnion extends Paths<T>> =
|
|
81
|
+
T extends NonRecursiveType
|
|
82
|
+
? never
|
|
83
|
+
: T extends UnknownArray
|
|
84
|
+
? UnionToIntersection<{
|
|
85
|
+
[P in PathUnion]: InternalPickDeep<T, P>;
|
|
86
|
+
}[PathUnion]
|
|
87
|
+
>
|
|
88
|
+
: T extends object
|
|
89
|
+
? Simplify<UnionToIntersection<{
|
|
90
|
+
[P in PathUnion]: InternalPickDeep<T, P>;
|
|
91
|
+
}[PathUnion]>>
|
|
92
|
+
: never;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
Pick an object/array from the given object/array by one path.
|
|
96
|
+
*/
|
|
97
|
+
type InternalPickDeep<T, Path extends string | number> =
|
|
98
|
+
T extends NonRecursiveType
|
|
99
|
+
? never
|
|
100
|
+
: T extends UnknownArray ? PickDeepArray<T, Path>
|
|
101
|
+
: T extends object ? Simplify<PickDeepObject<T, Path>>
|
|
102
|
+
: never;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Pick an object from the given object by one path.
|
|
106
|
+
*/
|
|
107
|
+
type PickDeepObject<RecordType extends object, P extends string | number> =
|
|
108
|
+
P extends `${infer RecordKeyInPath}.${infer SubPath}`
|
|
109
|
+
? ObjectValue<RecordType, RecordKeyInPath> extends infer ObjectV
|
|
110
|
+
? IsNever<ObjectV> extends false
|
|
111
|
+
? BuildObject<RecordKeyInPath, InternalPickDeep<NonNullable<ObjectV>, SubPath>, RecordType>
|
|
112
|
+
: never
|
|
113
|
+
: never
|
|
114
|
+
: ObjectValue<RecordType, P> extends infer ObjectV
|
|
115
|
+
? IsNever<ObjectV> extends false
|
|
116
|
+
? BuildObject<P, ObjectV, RecordType>
|
|
117
|
+
: never
|
|
118
|
+
: never;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
Pick an array from the given array by one path.
|
|
122
|
+
*/
|
|
123
|
+
type PickDeepArray<ArrayType extends UnknownArray, P extends string | number> =
|
|
124
|
+
// Handle paths that are `${number}.${string}`
|
|
125
|
+
P extends `${infer ArrayIndex extends number}.${infer SubPath}`
|
|
126
|
+
// When `ArrayIndex` is equal to `number`
|
|
127
|
+
? number extends ArrayIndex
|
|
128
|
+
? ArrayType extends unknown[]
|
|
129
|
+
? Array<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
|
|
130
|
+
: ArrayType extends readonly unknown[]
|
|
131
|
+
? ReadonlyArray<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
|
|
132
|
+
: never
|
|
133
|
+
// When `ArrayIndex` is a number literal
|
|
134
|
+
: ArrayType extends unknown[]
|
|
135
|
+
? [...TupleOf<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
|
|
136
|
+
: ArrayType extends readonly unknown[]
|
|
137
|
+
? readonly [...TupleOf<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
|
|
138
|
+
: never
|
|
139
|
+
// When the path is equal to `number`
|
|
140
|
+
: P extends `${infer ArrayIndex extends number}`
|
|
141
|
+
// When `ArrayIndex` is `number`
|
|
142
|
+
? number extends ArrayIndex
|
|
143
|
+
? ArrayType
|
|
144
|
+
// When `ArrayIndex` is a number literal
|
|
145
|
+
: ArrayType extends unknown[]
|
|
146
|
+
? [...TupleOf<ArrayIndex>, ArrayType[ArrayIndex]]
|
|
147
|
+
: ArrayType extends readonly unknown[]
|
|
148
|
+
? readonly [...TupleOf<ArrayIndex>, ArrayType[ArrayIndex]]
|
|
149
|
+
: never
|
|
150
|
+
: never;
|
|
151
|
+
|
|
152
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Pick only index signatures from the given object type, leaving out all explicitly defined properties.
|
|
3
|
+
|
|
4
|
+
This is the counterpart of `OmitIndexSignature`.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {PickIndexSignature} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
declare const symbolKey: unique symbol;
|
|
11
|
+
|
|
12
|
+
type Example = {
|
|
13
|
+
// These index signatures will remain.
|
|
14
|
+
[x: string]: unknown;
|
|
15
|
+
[x: number]: unknown;
|
|
16
|
+
[x: symbol]: unknown;
|
|
17
|
+
[x: `head-${string}`]: string;
|
|
18
|
+
[x: `${string}-tail`]: string;
|
|
19
|
+
[x: `head-${string}-tail`]: string;
|
|
20
|
+
[x: `${bigint}`]: string;
|
|
21
|
+
[x: `embedded-${number}`]: string;
|
|
22
|
+
|
|
23
|
+
// These explicitly defined keys will be removed.
|
|
24
|
+
['kebab-case-key']: string;
|
|
25
|
+
[symbolKey]: string;
|
|
26
|
+
foo: 'bar';
|
|
27
|
+
qux?: 'baz';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type ExampleIndexSignature = PickIndexSignature<Example>;
|
|
31
|
+
// {
|
|
32
|
+
// [x: string]: unknown;
|
|
33
|
+
// [x: number]: unknown;
|
|
34
|
+
// [x: symbol]: unknown;
|
|
35
|
+
// [x: `head-${string}`]: string;
|
|
36
|
+
// [x: `${string}-tail`]: string;
|
|
37
|
+
// [x: `head-${string}-tail`]: string;
|
|
38
|
+
// [x: `${bigint}`]: string;
|
|
39
|
+
// [x: `embedded-${number}`]: string;
|
|
40
|
+
// }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
@see {@link OmitIndexSignature}
|
|
44
|
+
@category Object
|
|
45
|
+
*/
|
|
46
|
+
export type PickIndexSignature<ObjectType> = {
|
|
47
|
+
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
48
|
+
? KeyType
|
|
49
|
+
: never]: ObjectType[KeyType];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Create a type that represents either the value or the value wrapped in `PromiseLike`.
|
|
3
|
+
|
|
4
|
+
Use-cases:
|
|
5
|
+
- A function accepts a callback that may either return a value synchronously or may return a promised value.
|
|
6
|
+
- This type could be the return type of `Promise#then()`, `Promise#catch()`, and `Promise#finally()` callbacks.
|
|
7
|
+
|
|
8
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31394) if you want to have this type as a built-in in TypeScript.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
import type {Promisable} from 'type-fest';
|
|
13
|
+
|
|
14
|
+
async function logger(getLogEntry: () => Promisable<string>): Promise<void> {
|
|
15
|
+
const entry = await getLogEntry();
|
|
16
|
+
console.log(entry);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
await logger(() => 'foo');
|
|
20
|
+
await logger(() => Promise.resolve('bar'));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
@category Async
|
|
24
|
+
*/
|
|
25
|
+
export type Promisable<T> = T | PromiseLike<T>;
|
|
26
|
+
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type {BuiltIns, HasMultipleCallSignatures} from './internal/index.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively.
|
|
5
|
+
|
|
6
|
+
This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around.
|
|
7
|
+
|
|
8
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
import type {ReadonlyDeep} from 'type-fest';
|
|
13
|
+
|
|
14
|
+
declare const foo: {
|
|
15
|
+
a: string;
|
|
16
|
+
b: {c: number};
|
|
17
|
+
d: Array<{e: number}>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
foo.a = 'bar'; // Allowed
|
|
21
|
+
|
|
22
|
+
foo.b = {c: 3}; // Allowed
|
|
23
|
+
|
|
24
|
+
foo.b.c = 4; // Allowed
|
|
25
|
+
|
|
26
|
+
foo.d = [{e: 5}]; // Allowed
|
|
27
|
+
|
|
28
|
+
foo.d.push({e: 6}); // Allowed
|
|
29
|
+
|
|
30
|
+
const last = foo.d.at(-1);
|
|
31
|
+
if (last) {
|
|
32
|
+
last.e = 7; // Allowed
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare const readonlyFoo: ReadonlyDeep<typeof foo>;
|
|
36
|
+
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
readonlyFoo.a = 'bar';
|
|
39
|
+
// Error: Cannot assign to 'a' because it is a read-only property.
|
|
40
|
+
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
readonlyFoo.b = {c: 3};
|
|
43
|
+
// Error: Cannot assign to 'b' because it is a read-only property.
|
|
44
|
+
|
|
45
|
+
// @ts-expect-error
|
|
46
|
+
readonlyFoo.b.c = 4;
|
|
47
|
+
// Error: Cannot assign to 'c' because it is a read-only property.
|
|
48
|
+
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
readonlyFoo.d = [{e: 5}];
|
|
51
|
+
// Error: Cannot assign to 'd' because it is a read-only property.
|
|
52
|
+
|
|
53
|
+
// @ts-expect-error
|
|
54
|
+
readonlyFoo.d.push({e: 6});
|
|
55
|
+
// Error: Property 'push' does not exist on type 'ReadonlyArray<{readonly e: number}>'.
|
|
56
|
+
|
|
57
|
+
const readonlyLast = readonlyFoo.d.at(-1);
|
|
58
|
+
if (readonlyLast) {
|
|
59
|
+
// @ts-expect-error
|
|
60
|
+
readonlyLast.e = 8;
|
|
61
|
+
// Error: Cannot assign to 'e' because it is a read-only property.
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Note that types containing overloaded functions are not made deeply readonly due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
|
|
66
|
+
|
|
67
|
+
@category Object
|
|
68
|
+
@category Array
|
|
69
|
+
@category Set
|
|
70
|
+
@category Map
|
|
71
|
+
*/
|
|
72
|
+
export type ReadonlyDeep<T> = T extends BuiltIns
|
|
73
|
+
? T
|
|
74
|
+
: T extends new (...arguments_: any[]) => unknown
|
|
75
|
+
? T // Skip class constructors
|
|
76
|
+
: T extends (...arguments_: any[]) => unknown
|
|
77
|
+
? {} extends _ReadonlyObjectDeep<T>
|
|
78
|
+
? T
|
|
79
|
+
: HasMultipleCallSignatures<T> extends true
|
|
80
|
+
? T
|
|
81
|
+
: ((...arguments_: Parameters<T>) => ReturnType<T>) & _ReadonlyObjectDeep<T>
|
|
82
|
+
: T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>>
|
|
83
|
+
? ReadonlyMapDeep<KeyType, ValueType>
|
|
84
|
+
: T extends Readonly<ReadonlySet<infer ItemType>>
|
|
85
|
+
? ReadonlySetDeep<ItemType>
|
|
86
|
+
: // Identify tuples to avoid converting them to arrays inadvertently; special case `readonly [...never[]]`, as it emerges undesirably from recursive invocations of ReadonlyDeep below.
|
|
87
|
+
T extends readonly [] | readonly [...never[]]
|
|
88
|
+
? readonly []
|
|
89
|
+
: T extends readonly [infer U, ...infer V]
|
|
90
|
+
? readonly [ReadonlyDeep<U>, ...ReadonlyDeep<V>]
|
|
91
|
+
: T extends readonly [...infer U, infer V]
|
|
92
|
+
? readonly [...ReadonlyDeep<U>, ReadonlyDeep<V>]
|
|
93
|
+
: T extends ReadonlyArray<infer ItemType>
|
|
94
|
+
? ReadonlyArray<ReadonlyDeep<ItemType>>
|
|
95
|
+
: T extends object
|
|
96
|
+
? _ReadonlyObjectDeep<T>
|
|
97
|
+
: unknown;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`.
|
|
101
|
+
*/
|
|
102
|
+
type ReadonlyMapDeep<KeyType, ValueType> = {} & Readonly<ReadonlyMap<ReadonlyDeep<KeyType>, ReadonlyDeep<ValueType>>>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`.
|
|
106
|
+
*/
|
|
107
|
+
type ReadonlySetDeep<ItemType> = {} & Readonly<ReadonlySet<ReadonlyDeep<ItemType>>>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`.
|
|
111
|
+
*/
|
|
112
|
+
export type _ReadonlyObjectDeep<ObjectType extends object> = {
|
|
113
|
+
readonly [KeyType in keyof ObjectType]: ReadonlyDeep<ObjectType[KeyType]>
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {IsReadonlyKeyOf} from './is-readonly-key-of.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Extract all readonly keys from the given type.
|
|
5
|
+
|
|
6
|
+
This is useful when you want to create a new type that contains readonly keys only.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {ReadonlyKeysOf} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type User = {
|
|
13
|
+
name: string;
|
|
14
|
+
surname: string;
|
|
15
|
+
|
|
16
|
+
readonly id: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type UpdateResponse<Entity extends object> = Pick<Entity, ReadonlyKeysOf<Entity>>;
|
|
20
|
+
|
|
21
|
+
const update1: UpdateResponse<User> = {
|
|
22
|
+
id: 123,
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
@category Utilities
|
|
27
|
+
*/
|
|
28
|
+
export type ReadonlyKeysOf<Type extends object> =
|
|
29
|
+
Type extends unknown // For distributing `Type`
|
|
30
|
+
? (keyof {[Key in keyof Type as
|
|
31
|
+
IsReadonlyKeyOf<Type, Key> extends false
|
|
32
|
+
? never
|
|
33
|
+
: Key
|
|
34
|
+
]: never
|
|
35
|
+
}) & keyof Type // Intersect with `keyof Type` to ensure result of `ReadonlyKeysOf<Type>` is always assignable to `keyof Type`
|
|
36
|
+
: never; // Should never happen
|
|
37
|
+
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type {TupleOf} from './tuple-of.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Create a type that represents a read-only tuple of the given type and length.
|
|
5
|
+
|
|
6
|
+
Use-cases:
|
|
7
|
+
- Declaring fixed-length tuples with a large number of items.
|
|
8
|
+
- Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types.
|
|
9
|
+
- Creating a tuple of coordinates with a static length, for example, length of 3 for a 3D vector.
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```
|
|
13
|
+
import type {ReadonlyTuple} from 'type-fest';
|
|
14
|
+
|
|
15
|
+
type FencingTeam = ReadonlyTuple<string, 3>;
|
|
16
|
+
|
|
17
|
+
const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];
|
|
18
|
+
|
|
19
|
+
// @ts-expect-error
|
|
20
|
+
const homeFencingTeam: FencingTeam = ['George', 'John'];
|
|
21
|
+
// Error: Type '[string, string]' is not assignable to type 'readonly [string, string, string]'.
|
|
22
|
+
|
|
23
|
+
// @ts-expect-error
|
|
24
|
+
guestFencingTeam.push('Sam');
|
|
25
|
+
// Error: Property 'push' does not exist on type 'readonly [string, string, string]'.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
@deprecated This type will be removed in the next major version. Use the built-in `Readonly` type in combination with the {@link TupleOf} type instead, like `Readonly<TupleOf<Length, Element>>`.
|
|
29
|
+
|
|
30
|
+
@category Utilities
|
|
31
|
+
*/
|
|
32
|
+
export type ReadonlyTuple<Element, Length extends number> = Readonly<TupleOf<Length, Element>>;
|
|
33
|
+
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions} from './internal/object.d.ts';
|
|
2
|
+
import type {IfNotAnyOrNever, Not} from './internal/type.d.ts';
|
|
3
|
+
import type {IsStringLiteral} from './is-literal.d.ts';
|
|
4
|
+
import type {Or} from './or.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
@see {@link RemovePrefix}
|
|
8
|
+
*/
|
|
9
|
+
export type RemovePrefixOptions = {
|
|
10
|
+
/**
|
|
11
|
+
When enabled, instantiations with non-literal prefixes (e.g., `string`, `Uppercase<string>`, `` `on${string}` ``) simply return `string`, since their precise structure cannot be statically determined.
|
|
12
|
+
|
|
13
|
+
Note: Disabling this option can produce misleading results that might not reflect the actual runtime behavior.
|
|
14
|
+
For example, ``RemovePrefix<'on-change', `${string}-`, {strict: false}>`` returns `'change'`, but at runtime, prefix could be `'handle-'` (which satisfies `` `${string}-` ``) and removing `'handle-'` from `'on-change'` would not result in `'change'`.
|
|
15
|
+
|
|
16
|
+
So, it is recommended to not disable this option unless you are aware of the implications.
|
|
17
|
+
|
|
18
|
+
@default true
|
|
19
|
+
|
|
20
|
+
@example
|
|
21
|
+
```
|
|
22
|
+
import type {RemovePrefix} from 'type-fest';
|
|
23
|
+
|
|
24
|
+
type A = RemovePrefix<'on-change', `${string}-`, {strict: true}>;
|
|
25
|
+
//=> string
|
|
26
|
+
|
|
27
|
+
type B = RemovePrefix<'on-change', `${string}-`, {strict: false}>;
|
|
28
|
+
//=> 'change'
|
|
29
|
+
|
|
30
|
+
type C = RemovePrefix<'on-change', string, {strict: true}>;
|
|
31
|
+
//=> string
|
|
32
|
+
|
|
33
|
+
type D = RemovePrefix<'on-change', string, {strict: false}>;
|
|
34
|
+
//=> 'n-change'
|
|
35
|
+
|
|
36
|
+
type E = RemovePrefix<`${string}/${number}`, `${string}/`, {strict: true}>;
|
|
37
|
+
//=> string
|
|
38
|
+
|
|
39
|
+
type F = RemovePrefix<`${string}/${number}`, `${string}/`, {strict: false}>;
|
|
40
|
+
//=> `${number}`
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Note: This option has no effect when only the input string type is non-literal. For example, ``RemovePrefix<`on-${string}`, 'on-'>`` will always return `string`.
|
|
44
|
+
|
|
45
|
+
@example
|
|
46
|
+
```
|
|
47
|
+
import type {RemovePrefix} from 'type-fest';
|
|
48
|
+
|
|
49
|
+
type A = RemovePrefix<`on-${string}`, 'on-', {strict: true}>;
|
|
50
|
+
//=> string
|
|
51
|
+
|
|
52
|
+
type B = RemovePrefix<`on-${string}`, 'on-', {strict: false}>;
|
|
53
|
+
//=> string
|
|
54
|
+
|
|
55
|
+
type C = RemovePrefix<`id-${number}`, 'id-', {strict: true}>;
|
|
56
|
+
//=> `${number}`
|
|
57
|
+
|
|
58
|
+
type D = RemovePrefix<`id-${number}`, 'id-', {strict: false}>;
|
|
59
|
+
//=> `${number}`
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Note: If it can be statically determined that the input string can never start with the specified non-literal prefix, then the input string is returned as-is, regardless of the value of this option.
|
|
63
|
+
For example, ``RemovePrefix<`${string}/${number}`, `${string}:`>`` returns `` `${string}/${number}` ``, since a string of type `` `${string}/${number}` `` can never start with a prefix of type `` `${string}:` ``.
|
|
64
|
+
```
|
|
65
|
+
import type {RemovePrefix} from 'type-fest';
|
|
66
|
+
|
|
67
|
+
type A = RemovePrefix<`${string}/${number}`, `${string}:`, {strict: true}>;
|
|
68
|
+
//=> `${string}/${number}`
|
|
69
|
+
|
|
70
|
+
type B = RemovePrefix<`${string}/${number}`, `${string}:`, {strict: false}>;
|
|
71
|
+
//=> `${string}/${number}`
|
|
72
|
+
|
|
73
|
+
type C = RemovePrefix<'on-change', `${number}-`, {strict: true}>;
|
|
74
|
+
//=> 'on-change'
|
|
75
|
+
|
|
76
|
+
type D = RemovePrefix<'on-change', `${number}-`, {strict: false}>;
|
|
77
|
+
//=> 'on-change'
|
|
78
|
+
```
|
|
79
|
+
*/
|
|
80
|
+
strict?: boolean;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
type DefaultRemovePrefixOptions = {
|
|
84
|
+
strict: true;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
Remove the specified prefix from the start of a string.
|
|
89
|
+
|
|
90
|
+
@example
|
|
91
|
+
```
|
|
92
|
+
import type {RemovePrefix} from 'type-fest';
|
|
93
|
+
|
|
94
|
+
type A = RemovePrefix<'on-change', 'on-'>;
|
|
95
|
+
//=> 'change'
|
|
96
|
+
|
|
97
|
+
type B = RemovePrefix<'sm:flex' | 'sm:p-4' | 'sm:gap-2', 'sm:'>;
|
|
98
|
+
//=> 'flex' | 'p-4' | 'gap-2'
|
|
99
|
+
|
|
100
|
+
type C = RemovePrefix<'on-change', 'off-'>;
|
|
101
|
+
//=> 'on-change'
|
|
102
|
+
|
|
103
|
+
type D = RemovePrefix<`handle${Capitalize<string>}`, 'handle'>;
|
|
104
|
+
//=> Capitalize<string>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
@see {@link RemovePrefixOptions}
|
|
108
|
+
|
|
109
|
+
@category String
|
|
110
|
+
@category Template literal
|
|
111
|
+
*/
|
|
112
|
+
export type RemovePrefix<S extends string, Prefix extends string, Options extends RemovePrefixOptions = {}> =
|
|
113
|
+
IfNotAnyOrNever<
|
|
114
|
+
S,
|
|
115
|
+
IfNotAnyOrNever<
|
|
116
|
+
Prefix,
|
|
117
|
+
_RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>>,
|
|
118
|
+
string,
|
|
119
|
+
S
|
|
120
|
+
>
|
|
121
|
+
>;
|
|
122
|
+
|
|
123
|
+
type _RemovePrefix<S extends string, Prefix extends string, Options extends Required<RemovePrefixOptions>> =
|
|
124
|
+
Prefix extends string // For distributing `Prefix`
|
|
125
|
+
? S extends `${Prefix}${infer Rest}`
|
|
126
|
+
? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true
|
|
127
|
+
? Rest
|
|
128
|
+
: string // Fallback to `string` when `Prefix` is non-literal and `strict` is disabled
|
|
129
|
+
: S // Return back `S` when `Prefix` is not present at the start of `S`
|
|
130
|
+
: never;
|
|
131
|
+
|
|
132
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
2
|
+
|
|
3
|
+
export type ReplaceOptions = {
|
|
4
|
+
all?: boolean;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
type DefaultReplaceOptions = {
|
|
8
|
+
all: false;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Represents a string with some or all matches replaced by a replacement.
|
|
13
|
+
|
|
14
|
+
Use-case:
|
|
15
|
+
- `kebab-case-path` to `dotted.path.notation`
|
|
16
|
+
- Changing date/time format: `01-08-2042` → `01/08/2042`
|
|
17
|
+
- Manipulation of type properties, for example, removal of prefixes
|
|
18
|
+
|
|
19
|
+
@example
|
|
20
|
+
```
|
|
21
|
+
import type {Replace} from 'type-fest';
|
|
22
|
+
|
|
23
|
+
declare function replace<
|
|
24
|
+
Input extends string,
|
|
25
|
+
Search extends string,
|
|
26
|
+
Replacement extends string,
|
|
27
|
+
>(
|
|
28
|
+
input: Input,
|
|
29
|
+
search: Search,
|
|
30
|
+
replacement: Replacement
|
|
31
|
+
): Replace<Input, Search, Replacement>;
|
|
32
|
+
|
|
33
|
+
declare function replaceAll<
|
|
34
|
+
Input extends string,
|
|
35
|
+
Search extends string,
|
|
36
|
+
Replacement extends string,
|
|
37
|
+
>(
|
|
38
|
+
input: Input,
|
|
39
|
+
search: Search,
|
|
40
|
+
replacement: Replacement
|
|
41
|
+
): Replace<Input, Search, Replacement, {all: true}>;
|
|
42
|
+
|
|
43
|
+
// The return type is the exact string literal, not just `string`.
|
|
44
|
+
|
|
45
|
+
replace('hello ?', '?', '🦄');
|
|
46
|
+
//=> 'hello 🦄'
|
|
47
|
+
|
|
48
|
+
replace('hello ??', '?', '❓');
|
|
49
|
+
//=> 'hello ❓?'
|
|
50
|
+
|
|
51
|
+
replaceAll('10:42:00', ':', '-');
|
|
52
|
+
//=> '10-42-00'
|
|
53
|
+
|
|
54
|
+
replaceAll('__userName__', '__', '');
|
|
55
|
+
//=> 'userName'
|
|
56
|
+
|
|
57
|
+
replaceAll('My Cool Title', ' ', '');
|
|
58
|
+
//=> 'MyCoolTitle'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
@category String
|
|
62
|
+
@category Template literal
|
|
63
|
+
*/
|
|
64
|
+
export type Replace<
|
|
65
|
+
Input extends string,
|
|
66
|
+
Search extends string,
|
|
67
|
+
Replacement extends string,
|
|
68
|
+
Options extends ReplaceOptions = {},
|
|
69
|
+
> = _Replace<Input, Search, Replacement, ApplyDefaultOptions<ReplaceOptions, DefaultReplaceOptions, Options>>;
|
|
70
|
+
|
|
71
|
+
type _Replace<
|
|
72
|
+
Input extends string,
|
|
73
|
+
Search extends string,
|
|
74
|
+
Replacement extends string,
|
|
75
|
+
Options extends Required<ReplaceOptions>,
|
|
76
|
+
Accumulator extends string = '',
|
|
77
|
+
> = Search extends string // For distributing `Search`
|
|
78
|
+
? Replacement extends string // For distributing `Replacement`
|
|
79
|
+
? Input extends `${infer Head}${Search}${infer Tail}`
|
|
80
|
+
? Options['all'] extends true
|
|
81
|
+
? _Replace<Tail, Search, Replacement, Options, `${Accumulator}${Head}${Replacement}`>
|
|
82
|
+
: `${Head}${Replacement}${Tail}`
|
|
83
|
+
: `${Accumulator}${Input}`
|
|
84
|
+
: never
|
|
85
|
+
: never;
|
|
86
|
+
|
|
87
|
+
export {};
|