UNPKG

2.46 kBTypeScriptView Raw
1import type {DelimiterCase} from './delimiter-case';
2import type {NonRecursiveType} from './internal';
3import type {UnknownArray} from './unknown-array';
4
5/**
6Convert object properties to delimiter case recursively.
7
8This can be useful when, for example, converting some API types from a different style.
9
10@see DelimiterCase
11@see DelimiterCasedProperties
12
13@example
14```
15import type {DelimiterCasedPropertiesDeep} from 'type-fest';
16
17interface User {
18 userId: number;
19 userName: string;
20}
21
22interface UserWithFriends {
23 userInfo: User;
24 userFriends: User[];
25}
26
27const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
28 'user-info': {
29 'user-id': 1,
30 'user-name': 'Tom',
31 },
32 'user-friends': [
33 {
34 'user-id': 2,
35 'user-name': 'Jerry',
36 },
37 {
38 'user-id': 3,
39 'user-name': 'Spike',
40 },
41 ],
42};
43```
44
45@category Change case
46@category Template literal
47@category Object
48*/
49export type DelimiterCasedPropertiesDeep<
50 Value,
51 Delimiter extends string,
52> = Value extends NonRecursiveType
53 ? Value
54 : Value extends UnknownArray
55 ? DelimiterCasedPropertiesArrayDeep<Value, Delimiter>
56 : Value extends Set<infer U>
57 ? Set<DelimiterCasedPropertiesDeep<U, Delimiter>> : {
58 [K in keyof Value as DelimiterCase<
59 K,
60 Delimiter
61 >]: DelimiterCasedPropertiesDeep<Value[K], Delimiter>;
62 };
63
64// This is a copy of CamelCasedPropertiesArrayDeep (see: camel-cased-properties-deep.d.ts).
65// These types should be kept in sync.
66type DelimiterCasedPropertiesArrayDeep<Value extends UnknownArray, Delimiter extends string> =
67 Value extends []
68 ? []
69 // Tailing spread array
70 : Value extends [infer U, ...infer V]
71 ? [DelimiterCasedPropertiesDeep<U, Delimiter>, ...DelimiterCasedPropertiesDeep<V, Delimiter>]
72 : Value extends readonly [infer U, ...infer V]
73 ? readonly [DelimiterCasedPropertiesDeep<U, Delimiter>, ...DelimiterCasedPropertiesDeep<V, Delimiter>]
74 // Leading spread array
75 : Value extends readonly [...infer U, infer V]
76 ? [...DelimiterCasedPropertiesDeep<U, Delimiter>, DelimiterCasedPropertiesDeep<V, Delimiter>]
77 : Value extends readonly [...infer U, infer V]
78 ? readonly [...DelimiterCasedPropertiesDeep<U, Delimiter>, DelimiterCasedPropertiesDeep<V, Delimiter>]
79 // Array
80 : Value extends Array<infer U>
81 ? Array<DelimiterCasedPropertiesDeep<U, Delimiter>>
82 : Value extends ReadonlyArray<infer U>
83 ? ReadonlyArray<DelimiterCasedPropertiesDeep<U, Delimiter>>
84 : never;