type-fest 4.40.0 → 4.41.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 +1 -0
- package/source/camel-cased-properties-deep.d.ts +5 -6
- package/source/delimiter-cased-properties-deep.d.ts +7 -7
- package/source/greater-than.d.ts +32 -27
- package/source/internal/type.d.ts +26 -0
- package/source/is-float.d.ts +0 -2
- package/source/less-than.d.ts +5 -1
- package/source/partial-deep.d.ts +29 -23
- package/source/pascal-cased-properties-deep.d.ts +6 -3
- package/source/require-all-or-none.d.ts +11 -2
- package/source/require-at-least-one.d.ts +13 -0
- package/source/require-exactly-one.d.ts +11 -0
- package/source/require-one-or-none.d.ts +11 -2
- package/source/set-non-nullable-deep.d.ts +83 -0
- package/source/set-optional.d.ts +0 -1
- package/source/set-readonly.d.ts +0 -1
- package/source/set-required.d.ts +0 -1
- package/source/shared-union-fields-deep.d.ts +1 -1
package/index.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export type {SetReadonly} from './source/set-readonly';
|
|
|
47
47
|
export type {SetRequired} from './source/set-required';
|
|
48
48
|
export type {SetRequiredDeep} from './source/set-required-deep';
|
|
49
49
|
export type {SetNonNullable} from './source/set-non-nullable';
|
|
50
|
+
export type {SetNonNullableDeep} from './source/set-non-nullable-deep';
|
|
50
51
|
export type {ValueOf} from './source/value-of';
|
|
51
52
|
export type {AsyncReturnType} from './source/async-return-type';
|
|
52
53
|
export type {ConditionalExcept} from './source/conditional-except';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -151,6 +151,7 @@ Click the type names for complete docs.
|
|
|
151
151
|
- [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required.
|
|
152
152
|
- [`SetRequiredDeep`](source/set-required-deep.d.ts) - Like `SetRequired` except it selects the keys deeply.
|
|
153
153
|
- [`SetNonNullable`](source/set-non-nullable.d.ts) - Create a type that makes the given keys non-nullable.
|
|
154
|
+
- [`SetNonNullableDeep`](source/set-non-nullable-deep.d.ts) - Create a type that makes the specified keys non-nullable (removes `null` and `undefined`), supports deeply nested key paths, and leaves all other keys unchanged.
|
|
154
155
|
- [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from.
|
|
155
156
|
- [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type.
|
|
156
157
|
- [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type.
|
|
@@ -68,12 +68,11 @@ type _CamelCasedPropertiesDeep<
|
|
|
68
68
|
? CamelCasedPropertiesArrayDeep<Value, Options>
|
|
69
69
|
: Value extends Set<infer U>
|
|
70
70
|
? Set<_CamelCasedPropertiesDeep<U, Options>>
|
|
71
|
-
:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
};
|
|
71
|
+
: Value extends object
|
|
72
|
+
? {
|
|
73
|
+
[K in keyof Value as CamelCase<K, Options>]: _CamelCasedPropertiesDeep<Value[K], Options>;
|
|
74
|
+
}
|
|
75
|
+
: Value;
|
|
77
76
|
|
|
78
77
|
// This is a copy of DelimiterCasedPropertiesArrayDeep (see: delimiter-cased-properties-deep.d.ts).
|
|
79
78
|
// These types should be kept in sync.
|
|
@@ -72,13 +72,13 @@ type _DelimiterCasedPropertiesDeep<
|
|
|
72
72
|
: Value extends UnknownArray
|
|
73
73
|
? DelimiterCasedPropertiesArrayDeep<Value, Delimiter, Options>
|
|
74
74
|
: Value extends Set<infer U>
|
|
75
|
-
? Set<_DelimiterCasedPropertiesDeep<U, Delimiter, Options>>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
? Set<_DelimiterCasedPropertiesDeep<U, Delimiter, Options>>
|
|
76
|
+
: Value extends object
|
|
77
|
+
? {
|
|
78
|
+
[K in keyof Value as DelimiterCase<K, Delimiter, Options>]:
|
|
79
|
+
_DelimiterCasedPropertiesDeep<Value[K], Delimiter, Options>
|
|
80
|
+
}
|
|
81
|
+
: Value;
|
|
82
82
|
|
|
83
83
|
// This is a copy of CamelCasedPropertiesArrayDeep (see: camel-cased-properties-deep.d.ts).
|
|
84
84
|
// These types should be kept in sync.
|
package/source/greater-than.d.ts
CHANGED
|
@@ -21,31 +21,36 @@ GreaterThan<1, 5>;
|
|
|
21
21
|
//=> false
|
|
22
22
|
```
|
|
23
23
|
*/
|
|
24
|
-
export type GreaterThan<A extends number, B extends number> =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
: [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
|
|
43
|
-
? [true, false] extends R
|
|
24
|
+
export type GreaterThan<A extends number, B extends number> =
|
|
25
|
+
A extends number // For distributing `A`
|
|
26
|
+
? B extends number // For distributing `B`
|
|
27
|
+
? number extends A | B
|
|
28
|
+
? never
|
|
29
|
+
: [
|
|
30
|
+
IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
|
|
31
|
+
IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
|
|
32
|
+
] extends infer R extends [boolean, boolean, boolean, boolean]
|
|
33
|
+
? Or<
|
|
34
|
+
And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
|
|
35
|
+
And<IsEqual<R[3], true>, IsEqual<R[1], false>>
|
|
36
|
+
> extends true
|
|
37
|
+
? true
|
|
38
|
+
: Or<
|
|
39
|
+
And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
|
|
40
|
+
And<IsEqual<R[2], true>, IsEqual<R[0], false>>
|
|
41
|
+
> extends true
|
|
44
42
|
? false
|
|
45
|
-
:
|
|
46
|
-
?
|
|
47
|
-
: [
|
|
48
|
-
?
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
: true extends R[number]
|
|
44
|
+
? false
|
|
45
|
+
: [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
|
|
46
|
+
? [true, false] extends R
|
|
47
|
+
? false
|
|
48
|
+
: [false, true] extends R
|
|
49
|
+
? true
|
|
50
|
+
: [false, false] extends R
|
|
51
|
+
? PositiveNumericStringGt<`${A}`, `${B}`>
|
|
52
|
+
: PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`>
|
|
53
|
+
: never
|
|
54
|
+
: never
|
|
55
|
+
: never // Should never happen
|
|
56
|
+
: never; // Should never happen
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {IsAny} from '../is-any';
|
|
1
2
|
import type {IsNever} from '../is-never';
|
|
2
3
|
import type {Primitive} from '../primitive';
|
|
3
4
|
|
|
@@ -111,3 +112,28 @@ type InternalIsUnion<T, U = T> =
|
|
|
111
112
|
? boolean extends Result ? true
|
|
112
113
|
: Result
|
|
113
114
|
: never; // Should never happen
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
An if-else-like type that resolves depending on whether the given type is `any` or `never`.
|
|
118
|
+
|
|
119
|
+
@example
|
|
120
|
+
```
|
|
121
|
+
// When `T` is a NOT `any` or `never` (like `string`) => Returns `IfNotAnyOrNever` branch
|
|
122
|
+
type A = IfNotAnyOrNever<string, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
123
|
+
//=> 'VALID'
|
|
124
|
+
|
|
125
|
+
// When `T` is `any` => Returns `IfAny` branch
|
|
126
|
+
type B = IfNotAnyOrNever<any, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
127
|
+
//=> 'IS_ANY'
|
|
128
|
+
|
|
129
|
+
// When `T` is `never` => Returns `IfNever` branch
|
|
130
|
+
type C = IfNotAnyOrNever<never, 'VALID', 'IS_ANY', 'IS_NEVER'>;
|
|
131
|
+
//=> 'IS_NEVER'
|
|
132
|
+
```
|
|
133
|
+
*/
|
|
134
|
+
export type IfNotAnyOrNever<T, IfNotAnyOrNever, IfAny = any, IfNever = never> =
|
|
135
|
+
IsAny<T> extends true
|
|
136
|
+
? IfAny
|
|
137
|
+
: IsNever<T> extends true
|
|
138
|
+
? IfNever
|
|
139
|
+
: IfNotAnyOrNever;
|
package/source/is-float.d.ts
CHANGED
package/source/less-than.d.ts
CHANGED
|
@@ -19,4 +19,8 @@ LessThan<1, 5>;
|
|
|
19
19
|
*/
|
|
20
20
|
export type LessThan<A extends number, B extends number> = number extends A | B
|
|
21
21
|
? never
|
|
22
|
-
: GreaterThanOrEqual<A, B> extends
|
|
22
|
+
: GreaterThanOrEqual<A, B> extends infer Result
|
|
23
|
+
? Result extends true
|
|
24
|
+
? false
|
|
25
|
+
: true
|
|
26
|
+
: never; // Should never happen
|
package/source/partial-deep.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {ApplyDefaultOptions, BuiltIns} from './internal';
|
|
2
|
+
import type {IsNever} from './is-never';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
@see {@link PartialDeep}
|
|
@@ -95,27 +96,29 @@ const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {
|
|
|
95
96
|
export type PartialDeep<T, Options extends PartialDeepOptions = {}> =
|
|
96
97
|
_PartialDeep<T, ApplyDefaultOptions<PartialDeepOptions, DefaultPartialDeepOptions, Options>>;
|
|
97
98
|
|
|
98
|
-
type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | ((
|
|
99
|
+
type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | ((new (...arguments_: any[]) => unknown))
|
|
99
100
|
? T
|
|
100
|
-
: T extends
|
|
101
|
-
?
|
|
102
|
-
: T extends
|
|
103
|
-
?
|
|
104
|
-
: T extends
|
|
105
|
-
?
|
|
106
|
-
: T extends
|
|
107
|
-
?
|
|
108
|
-
: T extends
|
|
109
|
-
?
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
101
|
+
: IsNever<keyof T> extends true // For functions with no properties
|
|
102
|
+
? T
|
|
103
|
+
: T extends Map<infer KeyType, infer ValueType>
|
|
104
|
+
? PartialMapDeep<KeyType, ValueType, Options>
|
|
105
|
+
: T extends Set<infer ItemType>
|
|
106
|
+
? PartialSetDeep<ItemType, Options>
|
|
107
|
+
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
108
|
+
? PartialReadonlyMapDeep<KeyType, ValueType, Options>
|
|
109
|
+
: T extends ReadonlySet<infer ItemType>
|
|
110
|
+
? PartialReadonlySetDeep<ItemType, Options>
|
|
111
|
+
: T extends object
|
|
112
|
+
? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
|
|
113
|
+
? Options['recurseIntoArrays'] extends true
|
|
114
|
+
? ItemType[] extends T // Test for arrays (non-tuples) specifically
|
|
115
|
+
? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
|
|
116
|
+
? ReadonlyArray<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
|
|
117
|
+
: Array<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
|
|
118
|
+
: PartialObjectDeep<T, Options> // Tuples behave properly
|
|
119
|
+
: T // If they don't opt into array testing, just use the original type
|
|
120
|
+
: PartialObjectDeep<T, Options>
|
|
121
|
+
: unknown;
|
|
119
122
|
|
|
120
123
|
/**
|
|
121
124
|
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
|
|
@@ -140,6 +143,9 @@ type PartialReadonlySetDeep<T, Options extends Required<PartialDeepOptions>> = {
|
|
|
140
143
|
/**
|
|
141
144
|
Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
|
|
142
145
|
*/
|
|
143
|
-
type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> =
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> =
|
|
147
|
+
(ObjectType extends (...arguments_: any) => unknown
|
|
148
|
+
? (...arguments_: Parameters<ObjectType>) => ReturnType<ObjectType>
|
|
149
|
+
: {}) & ({
|
|
150
|
+
[KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
|
|
151
|
+
});
|
|
@@ -54,6 +54,9 @@ type _PascalCasedPropertiesDeep<Value, Options extends Required<CamelCaseOptions
|
|
|
54
54
|
: Value extends Array<infer U>
|
|
55
55
|
? Array<_PascalCasedPropertiesDeep<U, Options>>
|
|
56
56
|
: Value extends Set<infer U>
|
|
57
|
-
? Set<_PascalCasedPropertiesDeep<U, Options>>
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
? Set<_PascalCasedPropertiesDeep<U, Options>>
|
|
58
|
+
: Value extends object
|
|
59
|
+
? {
|
|
60
|
+
[K in keyof Value as PascalCase<K, Options>]: _PascalCasedPropertiesDeep<Value[K], Options>;
|
|
61
|
+
}
|
|
62
|
+
: Value;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {IfAny} from './if-any';
|
|
2
|
+
import type {IfNever} from './if-never';
|
|
3
|
+
import type {IfNotAnyOrNever, RequireNone} from './internal';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
Requires all of the keys in the given object.
|
|
@@ -36,7 +38,14 @@ const responder2: RequireAllOrNone<Responder, 'text' | 'json'> = {
|
|
|
36
38
|
|
|
37
39
|
@category Object
|
|
38
40
|
*/
|
|
39
|
-
export type RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
41
|
+
export type RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
42
|
+
IfNotAnyOrNever<ObjectType,
|
|
43
|
+
IfNever<KeysType,
|
|
44
|
+
ObjectType,
|
|
45
|
+
_RequireAllOrNone<ObjectType, IfAny<KeysType, keyof ObjectType, KeysType>>
|
|
46
|
+
>>;
|
|
47
|
+
|
|
48
|
+
type _RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType> = (
|
|
40
49
|
| RequireAll<ObjectType, KeysType>
|
|
41
50
|
| RequireNone<KeysType>
|
|
42
51
|
) & Omit<ObjectType, KeysType>; // The rest of the keys.
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type {Except} from './except';
|
|
2
|
+
import type {IfAny} from './if-any';
|
|
3
|
+
import type {IfNever} from './if-never';
|
|
4
|
+
import type {IfNotAnyOrNever} from './internal';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
Create a type that requires at least one of the given keys. The remaining keys are kept as is.
|
|
@@ -24,6 +27,16 @@ const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = {
|
|
|
24
27
|
export type RequireAtLeastOne<
|
|
25
28
|
ObjectType,
|
|
26
29
|
KeysType extends keyof ObjectType = keyof ObjectType,
|
|
30
|
+
> =
|
|
31
|
+
IfNotAnyOrNever<ObjectType,
|
|
32
|
+
IfNever<KeysType,
|
|
33
|
+
never,
|
|
34
|
+
_RequireAtLeastOne<ObjectType, IfAny<KeysType, keyof ObjectType, KeysType>>
|
|
35
|
+
>>;
|
|
36
|
+
|
|
37
|
+
type _RequireAtLeastOne<
|
|
38
|
+
ObjectType,
|
|
39
|
+
KeysType extends keyof ObjectType,
|
|
27
40
|
> = {
|
|
28
41
|
// For each `Key` in `KeysType` make a mapped type:
|
|
29
42
|
[Key in KeysType]-?: Required<Pick<ObjectType, Key>> & // 1. Make `Key`'s type required
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import type {IfAny} from './if-any';
|
|
2
|
+
import type {IfNever} from './if-never';
|
|
3
|
+
import type {IfNotAnyOrNever} from './internal';
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
Create a type that requires exactly one of the given keys and disallows more. The remaining keys are kept as is.
|
|
3
7
|
|
|
@@ -28,6 +32,13 @@ const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {
|
|
|
28
32
|
@category Object
|
|
29
33
|
*/
|
|
30
34
|
export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
35
|
+
IfNotAnyOrNever<ObjectType,
|
|
36
|
+
IfNever<KeysType,
|
|
37
|
+
never,
|
|
38
|
+
_RequireExactlyOne<ObjectType, IfAny<KeysType, keyof ObjectType, KeysType>>
|
|
39
|
+
>>;
|
|
40
|
+
|
|
41
|
+
type _RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType> =
|
|
31
42
|
{[Key in KeysType]: (
|
|
32
43
|
Required<Pick<ObjectType, Key>> &
|
|
33
44
|
Partial<Record<Exclude<KeysType, Key>, never>>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {RequireExactlyOne} from './require-exactly-one';
|
|
2
|
-
import type {RequireNone} from './internal';
|
|
2
|
+
import type {IfNotAnyOrNever, RequireNone} from './internal';
|
|
3
|
+
import type {IfNever} from './if-never';
|
|
4
|
+
import type {IfAny} from './if-any';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
Create a type that requires exactly one of the given keys and disallows more, or none of the given keys. The remaining keys are kept as is.
|
|
@@ -31,7 +33,14 @@ const responder3: Responder = {
|
|
|
31
33
|
|
|
32
34
|
@category Object
|
|
33
35
|
*/
|
|
34
|
-
export type RequireOneOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
36
|
+
export type RequireOneOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
37
|
+
IfNotAnyOrNever<ObjectType,
|
|
38
|
+
IfNever<KeysType,
|
|
39
|
+
ObjectType,
|
|
40
|
+
_RequireOneOrNone<ObjectType, IfAny<KeysType, keyof ObjectType, KeysType>>
|
|
41
|
+
>>;
|
|
42
|
+
|
|
43
|
+
type _RequireOneOrNone<ObjectType, KeysType extends keyof ObjectType> = (
|
|
35
44
|
| RequireExactlyOne<ObjectType, KeysType>
|
|
36
45
|
| RequireNone<KeysType>
|
|
37
46
|
) & Omit<ObjectType, KeysType>; // Ignore unspecified keys.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type {NonRecursiveType, StringToNumber} from './internal';
|
|
2
|
+
import type {Paths} from './paths';
|
|
3
|
+
import type {SetNonNullable} from './set-non-nullable';
|
|
4
|
+
import type {Simplify} from './simplify';
|
|
5
|
+
import type {UnionToTuple} from './union-to-tuple';
|
|
6
|
+
import type {UnknownArray} from './unknown-array';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
Create a type that makes the specified keys non-nullable (removes `null` and `undefined`), supports deeply nested key paths, and leaves all other keys unchanged.
|
|
10
|
+
|
|
11
|
+
NOTE: Optional modifiers (`?`) are not removed from properties. For example, `SetNonNullableDeep<{foo?: string | null | undefined}, 'foo'>` will result in `{foo?: string}`.
|
|
12
|
+
|
|
13
|
+
@example
|
|
14
|
+
```
|
|
15
|
+
import type {SetNonNullableDeep} from 'type-fest';
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
name: string;
|
|
19
|
+
address: {
|
|
20
|
+
city: string | undefined;
|
|
21
|
+
street?: string | null;
|
|
22
|
+
};
|
|
23
|
+
contact: {
|
|
24
|
+
email?: string | null | undefined;
|
|
25
|
+
phone: string | undefined;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type UpdatedUser = SetNonNullableDeep<User, 'address.street' | 'contact.email' | 'contact.phone'>;
|
|
30
|
+
//=> {
|
|
31
|
+
// name: string;
|
|
32
|
+
// address: {
|
|
33
|
+
// city: string | undefined;
|
|
34
|
+
// street?: string;
|
|
35
|
+
// };
|
|
36
|
+
// contact: {
|
|
37
|
+
// email?: string;
|
|
38
|
+
// phone: string;
|
|
39
|
+
// };
|
|
40
|
+
// };
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
@example
|
|
44
|
+
```
|
|
45
|
+
import type {SetNonNullableDeep} from 'type-fest';
|
|
46
|
+
|
|
47
|
+
// Set specific indices in an array to be non-nullable.
|
|
48
|
+
type ArrayExample1 = SetNonNullableDeep<{a: [number | null, number | null, number | undefined]}, 'a.1' | 'a.2'>;
|
|
49
|
+
//=> {a: [number | null, number, number]}
|
|
50
|
+
|
|
51
|
+
// Optional modifier (`?`) is not removed.
|
|
52
|
+
type ArrayExample2 = SetNonNullableDeep<{a: [(number | null)?, (number | null)?]}, 'a.1'>;
|
|
53
|
+
//=> {a: [(number | null)?, number?]}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
@category Object
|
|
57
|
+
*/
|
|
58
|
+
export type SetNonNullableDeep<BaseType, KeyPaths extends Paths<BaseType>> =
|
|
59
|
+
SetNonNullableDeepHelper<BaseType, UnionToTuple<KeyPaths>>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
Internal helper for {@link SetNonNullableDeep}.
|
|
63
|
+
|
|
64
|
+
Recursively transforms the `BaseType` by applying {@link SetNonNullableDeepSinglePath} for each path in `KeyPathsTuple`.
|
|
65
|
+
*/
|
|
66
|
+
type SetNonNullableDeepHelper<BaseType, KeyPathsTuple extends UnknownArray> =
|
|
67
|
+
KeyPathsTuple extends [infer KeyPath, ...infer RestPaths]
|
|
68
|
+
? SetNonNullableDeepHelper<SetNonNullableDeepSinglePath<BaseType, KeyPath>, RestPaths>
|
|
69
|
+
: BaseType;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
Makes a single path non-nullable in `BaseType`.
|
|
73
|
+
*/
|
|
74
|
+
type SetNonNullableDeepSinglePath<BaseType, KeyPath> =
|
|
75
|
+
BaseType extends NonRecursiveType | ReadonlySet<unknown> | ReadonlyMap<unknown, unknown> // Also distributes `BaseType`
|
|
76
|
+
? BaseType
|
|
77
|
+
: KeyPath extends `${infer Property}.${infer RestPath}`
|
|
78
|
+
? {
|
|
79
|
+
[Key in keyof BaseType]: Property extends `${Key & (string | number)}`
|
|
80
|
+
? SetNonNullableDeepSinglePath<BaseType[Key], RestPath>
|
|
81
|
+
: BaseType[Key];
|
|
82
|
+
}
|
|
83
|
+
: Simplify<SetNonNullable<BaseType, (KeyPath | StringToNumber<KeyPath & string>) & keyof BaseType>>;
|
package/source/set-optional.d.ts
CHANGED
package/source/set-readonly.d.ts
CHANGED
package/source/set-required.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {Except} from './except';
|
|
2
2
|
import type {HomomorphicPick, IfArrayReadonly} from './internal';
|
|
3
|
-
import type {KeysOfUnion} from './keys-of-union';
|
|
4
3
|
import type {OptionalKeysOf} from './optional-keys-of';
|
|
5
4
|
import type {Simplify} from './simplify';
|
|
6
5
|
import type {UnknownArray} from './unknown-array';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {NonRecursiveType, UnionMin, UnionMax, TupleLength, StaticPartOfArray, VariablePartOfArray,
|
|
1
|
+
import type {NonRecursiveType, UnionMin, UnionMax, TupleLength, StaticPartOfArray, VariablePartOfArray, IsArrayReadonly, SetArrayAccess, ApplyDefaultOptions} from './internal';
|
|
2
2
|
import type {IsNever} from './is-never';
|
|
3
3
|
import type {UnknownArray} from './unknown-array';
|
|
4
4
|
|