@aryaemami59/tsconfig 0.0.5 → 0.0.7
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/LICENSE +1 -1
- package/README.md +1 -1
- package/package.json +206 -34
- package/scripts/build.ts +268 -0
- package/scripts/typeHelpers.ts +468 -0
- package/scripts/types.ts +1637 -0
- package/src/bundler/esnext/tsconfig.json +8 -0
- package/src/bundler/esnext/with-js/tsconfig.json +9 -0
- package/src/bundler/preserve/tsconfig.json +9 -0
- package/src/bundler/preserve/with-js/tsconfig.json +9 -0
- package/{create-react-app → src/create-react-app}/tsconfig.json +2 -2
- package/{base → src/node}/tsconfig.json +8 -5
- package/src/node/with-js/tsconfig.json +9 -0
- package/src/node-10/tsconfig.json +8 -0
- package/src/node-10/with-js/tsconfig.json +9 -0
- package/src/node-16/tsconfig.json +9 -0
- package/src/node-16/with-js/tsconfig.json +9 -0
- package/src/node-next/tsconfig.json +9 -0
- package/src/node-next/with-js/tsconfig.json +9 -0
- package/bundler/esnext/tsconfig.json +0 -8
- package/bundler/preserve/tsconfig.json +0 -9
- package/node-10/tsconfig.json +0 -8
- package/node-16/tsconfig.json +0 -9
- package/node-next/tsconfig.json +0 -9
- package/node-next/with-js/tsconfig.json +0 -9
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Any function with **`unknown`** arguments.
|
|
3
|
+
* You probably want this instead of {@linkcode Function}.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* <caption>Basic usage</caption>
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const fn = ((...args) => args.length) satisfies UnknownFunction;
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export type UnknownFunction = (...args: unknown[]) => unknown
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An alias for **`NonNullable<unknown>`**, which represents any value that is
|
|
19
|
+
* **not** `null` or `undefined`. This is primarily a semantic helper used to
|
|
20
|
+
* distinguish between:
|
|
21
|
+
*
|
|
22
|
+
* - the empty object type **`{}`**, which accepts all non-nullish values but
|
|
23
|
+
* conveys an “object-like” intent, and
|
|
24
|
+
* - **`NonNullable<unknown>`**, which explicitly means “any non-nullish value,”
|
|
25
|
+
* including primitives.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* <caption>Basic usage</caption>
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* // ✅ OK
|
|
32
|
+
* const a = 123 as const satisfies AnyNonNullishValue;
|
|
33
|
+
* const b = "hello" as const satisfies AnyNonNullishValue;
|
|
34
|
+
* const c = true as const satisfies AnyNonNullishValue;
|
|
35
|
+
* const d = {} as const satisfies AnyNonNullishValue;
|
|
36
|
+
* const e = [] as const satisfies AnyNonNullishValue;
|
|
37
|
+
* const f = (() => {
|
|
38
|
+
* console.log("hi");
|
|
39
|
+
* }) satisfies AnyNonNullishValue;
|
|
40
|
+
* const g = Symbol("x") satisfies AnyNonNullishValue;
|
|
41
|
+
*
|
|
42
|
+
* // ❌ Error
|
|
43
|
+
* // @ts-expect-error
|
|
44
|
+
* const h = null satisfies AnyNonNullishValue;
|
|
45
|
+
* // @ts-expect-error
|
|
46
|
+
* const i = undefined satisfies AnyNonNullishValue;
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
export type AnyNonNullishValue = NonNullable<unknown>
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Useful to flatten the type output to improve type hints shown in editors.
|
|
56
|
+
* And also to transform an interface into a type to aide with assignability.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* <caption>Basic usage</caption>
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* interface SomeInterface {
|
|
63
|
+
* bar?: string;
|
|
64
|
+
* baz: number | undefined;
|
|
65
|
+
* foo: number;
|
|
66
|
+
* }
|
|
67
|
+
*
|
|
68
|
+
* type SomeType = {
|
|
69
|
+
* bar?: string;
|
|
70
|
+
* baz: number | undefined;
|
|
71
|
+
* foo: number;
|
|
72
|
+
* };
|
|
73
|
+
*
|
|
74
|
+
* const literal = {
|
|
75
|
+
* bar: "hello",
|
|
76
|
+
* baz: 456,
|
|
77
|
+
* foo: 123,
|
|
78
|
+
* } as const satisfies SomeType satisfies SomeInterface;
|
|
79
|
+
*
|
|
80
|
+
* const someType: SomeType = literal;
|
|
81
|
+
* const someInterface: SomeInterface = literal;
|
|
82
|
+
*
|
|
83
|
+
* function fn(object: Record<string, unknown>): void {
|
|
84
|
+
* console.log(object);
|
|
85
|
+
* };
|
|
86
|
+
*
|
|
87
|
+
* fn(literal); // ✅ Good: literal object type is sealed
|
|
88
|
+
* fn(someType); // ✅ Good: type is sealed
|
|
89
|
+
* // @ts-expect-error
|
|
90
|
+
* fn(someInterface); // ❌ Error: Index signature for type "string" is missing in type "someInterface". Because `interface` can be re-opened
|
|
91
|
+
* fn(someInterface as Simplify<SomeInterface>); // ✅ Good: transform an `interface` into a `type`
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @template BaseType - The type to simplify.
|
|
95
|
+
*
|
|
96
|
+
* @see {@link https://github.com/sindresorhus/type-fest/blob/2300245cb6f0b28ee36c2bb852ade872254073b8/source/simplify.d.ts Source}
|
|
97
|
+
* @see {@link https://github.com/microsoft/TypeScript/issues/15300 | TypeScript Issue}
|
|
98
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
export type Simplify<BaseType> = BaseType extends BaseType
|
|
102
|
+
? BaseType extends UnknownFunction
|
|
103
|
+
? BaseType
|
|
104
|
+
: AnyNonNullishValue & {
|
|
105
|
+
[KeyType in keyof BaseType]: BaseType[KeyType]
|
|
106
|
+
}
|
|
107
|
+
: never
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Omits keys from a type, **distributing** the operation over a union.
|
|
111
|
+
* TypeScript's {@linkcode Omit} does **not** distribute over unions,
|
|
112
|
+
* which can lead to the erasure of unique properties from union members
|
|
113
|
+
* when omitting keys. This causes the resulting type to retain only
|
|
114
|
+
* properties common to all union members, making it impossible to access
|
|
115
|
+
* member-specific properties after using {@linkcode Omit}.
|
|
116
|
+
* In other words, using {@linkcode Omit} on a union merges its members into
|
|
117
|
+
* a less specific type, breaking type narrowing and property access based
|
|
118
|
+
* on discriminants. This utility solves that limitation by applying
|
|
119
|
+
* {@linkcode Omit} distributively to each union member.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* <caption>Demonstrating `Omit` vs `DistributedOmit`</caption>
|
|
123
|
+
*
|
|
124
|
+
* ```ts
|
|
125
|
+
* type A = {
|
|
126
|
+
* a: number;
|
|
127
|
+
* discriminant: "A";
|
|
128
|
+
* foo: string;
|
|
129
|
+
* };
|
|
130
|
+
*
|
|
131
|
+
* type B = {
|
|
132
|
+
* b: string;
|
|
133
|
+
* discriminant: "B";
|
|
134
|
+
* foo: string;
|
|
135
|
+
* };
|
|
136
|
+
*
|
|
137
|
+
* type Union = A | B;
|
|
138
|
+
*
|
|
139
|
+
* const omittedUnion: Omit<Union, "foo"> = {
|
|
140
|
+
* discriminant: "A",
|
|
141
|
+
* };
|
|
142
|
+
*
|
|
143
|
+
* if (omittedUnion.discriminant === "A") {
|
|
144
|
+
* // We would like to narrow `omittedUnion`'s type to `A` here,
|
|
145
|
+
* // but we can't because `Omit` doesn't distribute over unions.
|
|
146
|
+
*
|
|
147
|
+
* // @ts-expect-error
|
|
148
|
+
* omittedUnion.a;
|
|
149
|
+
* // => ❌ Error: Property 'a' does not exist on type '{ discriminant: "A" | "B" }'
|
|
150
|
+
* }
|
|
151
|
+
*
|
|
152
|
+
* const distributedOmittedUnion: DistributedOmit<Union, "foo"> = {
|
|
153
|
+
* a: 123,
|
|
154
|
+
* discriminant: "A",
|
|
155
|
+
* };
|
|
156
|
+
*
|
|
157
|
+
* if (distributedOmittedUnion.discriminant === "A") {
|
|
158
|
+
* // We can successfully narrow `distributedOmittedUnion`'s type to `A` here,
|
|
159
|
+
* // because `DistributedOmit` distributes over unions.
|
|
160
|
+
*
|
|
161
|
+
* distributedOmittedUnion.a;
|
|
162
|
+
* // => ✅ OK
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @template ObjectType - The base object or union type to omit properties from.
|
|
167
|
+
* @template KeyType - The keys of {@linkcode ObjectType} to omit.
|
|
168
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
export type DistributedOmit<
|
|
172
|
+
ObjectType,
|
|
173
|
+
KeyType extends keyof ObjectType,
|
|
174
|
+
> = ObjectType extends unknown ? Omit<ObjectType, KeyType> : never
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Picks keys from a type, **distributing** the operation over a union.
|
|
178
|
+
* TypeScript's {@linkcode Pick} does **not** distribute over unions,
|
|
179
|
+
* which can lead to the erasure of unique properties from union members
|
|
180
|
+
* when picking keys. This causes the resulting type to retain only
|
|
181
|
+
* properties common to all union members, making it impossible to access
|
|
182
|
+
* member-specific properties after using {@linkcode Pick}.
|
|
183
|
+
* In other words, using {@linkcode Pick} on a union merges its members into
|
|
184
|
+
* a less specific type, breaking type narrowing and property access based
|
|
185
|
+
* on discriminants. This utility solves that limitation by applying
|
|
186
|
+
* {@linkcode Pick} distributively to each union member.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* <caption>Demonstrating `Pick` vs `DistributedPick`</caption>
|
|
190
|
+
*
|
|
191
|
+
* ```ts
|
|
192
|
+
* type A = {
|
|
193
|
+
* discriminant: "A";
|
|
194
|
+
* extraneous: boolean;
|
|
195
|
+
* foo: {
|
|
196
|
+
* bar: string;
|
|
197
|
+
* };
|
|
198
|
+
* };
|
|
199
|
+
*
|
|
200
|
+
* type B = {
|
|
201
|
+
* discriminant: "B";
|
|
202
|
+
* extraneous: boolean;
|
|
203
|
+
* foo: {
|
|
204
|
+
* baz: string;
|
|
205
|
+
* };
|
|
206
|
+
* };
|
|
207
|
+
*
|
|
208
|
+
* // Notice that `foo.bar` exists in `A` but not in `B`.
|
|
209
|
+
*
|
|
210
|
+
* type Union = A | B;
|
|
211
|
+
*
|
|
212
|
+
* const pickedUnion: Pick<Union, "discriminant" | "foo"> = {
|
|
213
|
+
* discriminant: "A",
|
|
214
|
+
* foo: {
|
|
215
|
+
* bar: "",
|
|
216
|
+
* },
|
|
217
|
+
* };
|
|
218
|
+
*
|
|
219
|
+
* if (pickedUnion.discriminant === "A") {
|
|
220
|
+
* // We would like to narrow to `A` here,
|
|
221
|
+
* // but we can't because `Pick` doesn't distribute over unions.
|
|
222
|
+
*
|
|
223
|
+
* // @ts-expect-error
|
|
224
|
+
* pickedUnion.foo.bar;
|
|
225
|
+
* //=> ❌ Error: Property 'bar' does not exist on type '{ bar: string; } | { baz: string; }'.
|
|
226
|
+
*
|
|
227
|
+
* // @ts-expect-error
|
|
228
|
+
* pickedUnion.extraneous;
|
|
229
|
+
* //=> ❌ Error: Property 'extraneous' does not exist on type 'Pick<Union, "discriminant" | "foo">'.
|
|
230
|
+
*
|
|
231
|
+
* // @ts-expect-error
|
|
232
|
+
* pickedUnion.foo.baz;
|
|
233
|
+
* // => ❌ Error: Property 'baz' does not exist on type '{ bar: string; } | { baz: string; }'.
|
|
234
|
+
* }
|
|
235
|
+
*
|
|
236
|
+
* const distributedPickedUnion: DistributedPick<Union, "discriminant" | "foo"> = {
|
|
237
|
+
* discriminant: "A",
|
|
238
|
+
* foo: {
|
|
239
|
+
* bar: "",
|
|
240
|
+
* },
|
|
241
|
+
* };
|
|
242
|
+
*
|
|
243
|
+
* if (distributedPickedUnion.discriminant === "A") {
|
|
244
|
+
* // Narrowing works correctly because the pick is applied per union member.
|
|
245
|
+
*
|
|
246
|
+
* distributedPickedUnion.foo.bar;
|
|
247
|
+
* // => ✅ OK
|
|
248
|
+
*
|
|
249
|
+
* // @ts-expect-error
|
|
250
|
+
* distributedPickedUnion.extraneous;
|
|
251
|
+
* //=> ❌ Error: Property 'extraneous' does not exist on type 'Pick<A, "discriminant" | "foo">'.
|
|
252
|
+
*
|
|
253
|
+
* // @ts-expect-error
|
|
254
|
+
* distributedPickedUnion.foo.baz;
|
|
255
|
+
* //=> ❌ Error: Property 'baz' does not exist on type '{ bar: string; }'.
|
|
256
|
+
* }
|
|
257
|
+
* ```
|
|
258
|
+
*
|
|
259
|
+
* @template ObjectType - The base object or union type to pick properties from.
|
|
260
|
+
* @template KeyType - The keys of {@linkcode ObjectType} to pick.
|
|
261
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
262
|
+
* @internal
|
|
263
|
+
*/
|
|
264
|
+
export type DistributedPick<
|
|
265
|
+
ObjectType,
|
|
266
|
+
KeyType extends keyof ObjectType,
|
|
267
|
+
> = ObjectType extends unknown ? Pick<ObjectType, KeyType> : never
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* A stricter version of
|
|
271
|
+
* {@linkcode Extract | Extract<BaseType, TypeToExtract>} that ensures
|
|
272
|
+
* every member of {@linkcode TypeToExtract} can successfully extract
|
|
273
|
+
* something from {@linkcode BaseType}.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* <caption>Basic Usage</caption>
|
|
277
|
+
*
|
|
278
|
+
* ```ts
|
|
279
|
+
* type Example = ExtractStrict<"l" | "m" | "s" | "xl" | "xs", "s" | "xs">;
|
|
280
|
+
* //=> "s" | "xs"
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* @template BaseType - The base type to extract from.
|
|
284
|
+
* @template TypeToExtract - The type(s) to extract from {@linkcode BaseType}.
|
|
285
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
286
|
+
* @internal
|
|
287
|
+
*/
|
|
288
|
+
export type ExtractStrict<
|
|
289
|
+
BaseType,
|
|
290
|
+
TypeToExtract extends [TypeToExtract] extends [
|
|
291
|
+
TypeToExtract extends unknown
|
|
292
|
+
? Extract<BaseType, TypeToExtract> extends never
|
|
293
|
+
? never
|
|
294
|
+
: TypeToExtract
|
|
295
|
+
: never,
|
|
296
|
+
]
|
|
297
|
+
? unknown
|
|
298
|
+
: BaseType,
|
|
299
|
+
> = Extract<BaseType, TypeToExtract>
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* A stricter version of
|
|
303
|
+
* {@linkcode Exclude | Exclude<BaseType, TypesToExclude>} that ensures
|
|
304
|
+
* every member of {@linkcode TypesToExclude} can successfully exclude
|
|
305
|
+
* something from {@linkcode BaseType}.
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* <caption>Basic Usage</caption>
|
|
309
|
+
*
|
|
310
|
+
* ```ts
|
|
311
|
+
* type Example = ExcludeStrict<"l" | "m" | "s" | "xl" | "xs", "s" | "xs">;
|
|
312
|
+
* //=> "l" | "m" | "xl"
|
|
313
|
+
* ```
|
|
314
|
+
*
|
|
315
|
+
* @template BaseType - The base type to exclude from.
|
|
316
|
+
* @template TypesToExclude - The type(s) to exclude from {@linkcode BaseType}.
|
|
317
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
320
|
+
export type ExcludeStrict<
|
|
321
|
+
BaseType,
|
|
322
|
+
TypesToExclude extends [TypesToExclude] extends [
|
|
323
|
+
TypesToExclude extends unknown
|
|
324
|
+
? [BaseType] extends [Exclude<BaseType, TypesToExclude>]
|
|
325
|
+
? never
|
|
326
|
+
: TypesToExclude
|
|
327
|
+
: never,
|
|
328
|
+
]
|
|
329
|
+
? unknown
|
|
330
|
+
: BaseType,
|
|
331
|
+
> = Exclude<BaseType, TypesToExclude>
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Convert a string literal to kebab-case.
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* <caption>Basic usage</caption>
|
|
338
|
+
*
|
|
339
|
+
* ```ts
|
|
340
|
+
* const someVariable = "foo-bar" as const satisfies KebabCase<"fooBar">;
|
|
341
|
+
* ```
|
|
342
|
+
*
|
|
343
|
+
* @template StringType - The string literal type to convert to kebab-case.
|
|
344
|
+
* @template FirstRun - Internal helper to avoid prefixing the first character with a hyphen.
|
|
345
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
346
|
+
* @internal
|
|
347
|
+
* @see {@link https://stackoverflow.com/a/66140779 Source}
|
|
348
|
+
*/
|
|
349
|
+
export type KebabCase<
|
|
350
|
+
StringType extends string,
|
|
351
|
+
FirstRun extends boolean = true,
|
|
352
|
+
> = StringType extends `${infer FirstCharacter}${infer RemainingString}`
|
|
353
|
+
? `${FirstCharacter extends Lowercase<FirstCharacter>
|
|
354
|
+
? FirstCharacter extends `${number}`
|
|
355
|
+
? RemainingString extends `${number}`
|
|
356
|
+
? '-'
|
|
357
|
+
: ''
|
|
358
|
+
: ''
|
|
359
|
+
: FirstRun extends true
|
|
360
|
+
? ''
|
|
361
|
+
: '-'}${Lowercase<FirstCharacter>}${KebabCase<RemainingString, false>}`
|
|
362
|
+
: StringType
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Extracts only the **lowercase** string literal members from a given string
|
|
366
|
+
* literal type. This is especially useful when you have a union that mixes
|
|
367
|
+
* lowercase and capitalized variants and you want to keep only the canonical
|
|
368
|
+
* lowercase ones.
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* <caption>Basic usage</caption>
|
|
372
|
+
*
|
|
373
|
+
* ```ts
|
|
374
|
+
* type ModuleResolution =
|
|
375
|
+
* | "bundler"
|
|
376
|
+
* | "Bundler"
|
|
377
|
+
* | "classic"
|
|
378
|
+
* | "Classic"
|
|
379
|
+
* | "node"
|
|
380
|
+
* | "Node"
|
|
381
|
+
* | "node10"
|
|
382
|
+
* | "Node10"
|
|
383
|
+
* | "node16"
|
|
384
|
+
* | "Node16"
|
|
385
|
+
* | "nodenext"
|
|
386
|
+
* | "NodeNext";
|
|
387
|
+
*
|
|
388
|
+
* type LowercaseModuleResolution = ExtractLowercase<ModuleResolution>;
|
|
389
|
+
* // ^? "bundler" | "classic" | "node" | "node10" | "node16" | "nodenext"
|
|
390
|
+
* ```
|
|
391
|
+
*
|
|
392
|
+
* @template StringType - A string literal type to filter.
|
|
393
|
+
* @see {@linkcode Lowercase} - The built-in utility used to test lowercase values.
|
|
394
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
395
|
+
* @internal
|
|
396
|
+
*/
|
|
397
|
+
export type ExtractLowercase<StringType extends string> =
|
|
398
|
+
StringType extends Lowercase<StringType> ? StringType : never
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Extracts only the **capitalized** (PascalCase-style) string literal members
|
|
402
|
+
* from a given string literal type. Each member of {@linkcode StringType} is
|
|
403
|
+
* evaluated using TypeScript's {@linkcode Capitalize} helper, and only those
|
|
404
|
+
* that are already capitalized are retained. All others resolve to `never`,
|
|
405
|
+
* effectively filtering them out of a union.
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* <caption>Basic usage</caption>
|
|
409
|
+
*
|
|
410
|
+
* ```ts
|
|
411
|
+
* type ModuleResolution =
|
|
412
|
+
* | "bundler"
|
|
413
|
+
* | "Bundler"
|
|
414
|
+
* | "classic"
|
|
415
|
+
* | "Classic"
|
|
416
|
+
* | "node"
|
|
417
|
+
* | "Node"
|
|
418
|
+
* | "node10"
|
|
419
|
+
* | "Node10"
|
|
420
|
+
* | "node16"
|
|
421
|
+
* | "Node16"
|
|
422
|
+
* | "nodenext"
|
|
423
|
+
* | "NodeNext";
|
|
424
|
+
*
|
|
425
|
+
* type CapitalizedModuleResolution = ExtractCapitalized<ModuleResolution>;
|
|
426
|
+
* // ^? "Bundler" | "Classic" | "Node" | "Node10" | "Node16" | "NodeNext"
|
|
427
|
+
* ```
|
|
428
|
+
*
|
|
429
|
+
* @template StringType - The string literal type to filter.
|
|
430
|
+
* @see {@linkcode Capitalize} - The built-in utility used to test capitalization.
|
|
431
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
432
|
+
* @internal
|
|
433
|
+
*/
|
|
434
|
+
export type ExtractCapitalized<StringType extends string> =
|
|
435
|
+
StringType extends Capitalize<StringType> ? StringType : never
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Produces a **widened string type** that still preserves autocomplete for the
|
|
439
|
+
* provided string literal union. Given a union of string literals, this utility
|
|
440
|
+
* returns a type that:
|
|
441
|
+
*
|
|
442
|
+
* - retains all literal members of {@linkcode StringType}, and
|
|
443
|
+
* - widens the union to `string & AnyNonNullishValue` to allow arbitrary
|
|
444
|
+
* user-provided strings while still supporting IDE completions for the known
|
|
445
|
+
* literals.
|
|
446
|
+
*
|
|
447
|
+
* This pattern is commonly used in configuration APIs where known literal
|
|
448
|
+
* options are suggested but custom strings must also be allowed.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* <caption>Preserving autocomplete while allowing any string</caption>
|
|
452
|
+
*
|
|
453
|
+
* ```ts
|
|
454
|
+
* type JsxFactory = StringLiteralUnion<"React.createElement">;
|
|
455
|
+
* // ^? "React.createElement" | (string & {})
|
|
456
|
+
*
|
|
457
|
+
* const a = "React.createElement" as const satisfies JsxFactory; // ✅ OK — literal member
|
|
458
|
+
* const b = "h" as const satisfies JsxFactory; // ✅ OK — arbitrary string allowed
|
|
459
|
+
* ```
|
|
460
|
+
*
|
|
461
|
+
* @template StringType - The string literal union to widen.
|
|
462
|
+
* @since v0.0.6 of **`@aryaemami59/tsconfig`**
|
|
463
|
+
* @internal
|
|
464
|
+
*/
|
|
465
|
+
export type StringLiteralUnion<StringType extends string> =
|
|
466
|
+
StringType extends StringType
|
|
467
|
+
? (string & AnyNonNullishValue) | StringType
|
|
468
|
+
: never
|