UNPKG

2.83 kBTypeScriptView Raw
1import type {BuiltIns, HasMultipleCallSignatures} from './internal';
2
3type ExcludeUndefined<T> = Exclude<T, undefined>;
4
5/**
6Create a type from another type with all keys and nested keys set to required.
7
8Use-cases:
9- Creating optional configuration interfaces where the underlying implementation still requires all options to be fully specified.
10- Modeling the resulting type after a deep merge with a set of defaults.
11
12@example
13```
14import type {RequiredDeep} from 'type-fest';
15
16type Settings = {
17 textEditor?: {
18 fontSize?: number | undefined;
19 fontColor?: string | undefined;
20 fontWeight?: number | undefined;
21 }
22 autocomplete?: boolean | undefined;
23 autosave?: boolean | undefined;
24};
25
26type RequiredSettings = RequiredDeep<Settings>;
27// type RequiredSettings = {
28// textEditor: {
29// fontSize: number;
30// fontColor: string;
31// fontWeight: number;
32// }
33// autocomplete: boolean;
34// autosave: boolean;
35// }
36```
37
38Note that types containing overloaded functions are not made deeply required due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
39
40@category Utilities
41@category Object
42@category Array
43@category Set
44@category Map
45*/
46export type RequiredDeep<T, E extends ExcludeUndefined<T> = ExcludeUndefined<T>> = E extends BuiltIns
47 ? E
48 : E extends Map<infer KeyType, infer ValueType>
49 ? Map<RequiredDeep<KeyType>, RequiredDeep<ValueType>>
50 : E extends Set<infer ItemType>
51 ? Set<RequiredDeep<ItemType>>
52 : E extends ReadonlyMap<infer KeyType, infer ValueType>
53 ? ReadonlyMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>>
54 : E extends ReadonlySet<infer ItemType>
55 ? ReadonlySet<RequiredDeep<ItemType>>
56 : E extends WeakMap<infer KeyType, infer ValueType>
57 ? WeakMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>>
58 : E extends WeakSet<infer ItemType>
59 ? WeakSet<RequiredDeep<ItemType>>
60 : E extends Promise<infer ValueType>
61 ? Promise<RequiredDeep<ValueType>>
62 : E extends (...arguments_: any[]) => unknown
63 ? {} extends RequiredObjectDeep<E>
64 ? E
65 : HasMultipleCallSignatures<E> extends true
66 ? E
67 : ((...arguments_: Parameters<E>) => ReturnType<E>) & RequiredObjectDeep<E>
68 : E extends object
69 ? E extends Array<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
70 ? ItemType[] extends E // Test for arrays (non-tuples) specifically
71 ? Array<RequiredDeep<ItemType>> // Recreate relevant array type to prevent eager evaluation of circular reference
72 : RequiredObjectDeep<E> // Tuples behave properly
73 : RequiredObjectDeep<E>
74 : unknown;
75
76type RequiredObjectDeep<ObjectType extends object> = {
77 [KeyType in keyof ObjectType]-?: RequiredDeep<ObjectType[KeyType]>
78};
79
\No newline at end of file