@elliemae/ds-typescript-helpers 3.46.5 → 3.46.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/package.json +3 -3
- package/dist/types/index.d.ts +0 -395
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-typescript-helpers",
|
|
3
|
-
"version": "3.46.
|
|
3
|
+
"version": "3.46.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Typescript helpers",
|
|
6
6
|
"files": [
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@elliemae/pui-cli": "9.0.0-next.50",
|
|
37
|
-
"@elliemae/ds-monorepo-devops": "3.46.
|
|
37
|
+
"@elliemae/ds-monorepo-devops": "3.46.7"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public",
|
|
41
|
-
"typeSafety":
|
|
41
|
+
"typeSafety": false
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"dev": "cross-env NODE_ENV=development node ../../../scripts/build/build.mjs --watch",
|
package/dist/types/index.d.ts
DELETED
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
export declare namespace TypescriptHelpersT {
|
|
3
|
-
/** ***************************************************************************
|
|
4
|
-
* A11y Helpers
|
|
5
|
-
**************************************************************************** */
|
|
6
|
-
/**
|
|
7
|
-
* WCAG recommends to not use tabindex values greater than 0 to ensure that the tab order is predictable.
|
|
8
|
-
* @example
|
|
9
|
-
* const tabIndex: WCAGTabIndex = 0; // valid
|
|
10
|
-
* const tabIndex: WCAGTabIndex = -1; // valid
|
|
11
|
-
*
|
|
12
|
-
* const tabIndex: WCAGTabIndex = 1; // invalid
|
|
13
|
-
* const tabIndex: WCAGTabIndex = "1"; // invalid
|
|
14
|
-
* const tabIndex: WCAGTabIndex = "0"; // invalid
|
|
15
|
-
* const tabIndex: WCAGTabIndex = "-1"; // invalid
|
|
16
|
-
*/
|
|
17
|
-
type WCAGTabIndex = 0 | -1;
|
|
18
|
-
/** ***************************************************************************
|
|
19
|
-
* Function Helpers
|
|
20
|
-
**************************************************************************** */
|
|
21
|
-
/**
|
|
22
|
-
* Helper for declaring generic functions easly. This is usually painful because of the argument spreading
|
|
23
|
-
* @example
|
|
24
|
-
* const myFunction: GenericFunc<number,void> = (a) => { console.log(a) }; // a is a number
|
|
25
|
-
* const myFunction2: GenericFunc<[number, number], string> = (a,b) => `${a + b}`; // a and b are numbers, the return type is a string
|
|
26
|
-
*/
|
|
27
|
-
type GenericFunc<T = unknown, R = unknown> = (...args: T extends Array<unknown> ? T : T[]) => R;
|
|
28
|
-
/**
|
|
29
|
-
* Helper for declaring a void function easly. This is usually painful because of the argument spreading.
|
|
30
|
-
* @example
|
|
31
|
-
* const myFunction: VoidGenericFunc<number> = (a) => { console.log(a) }; // a is a number
|
|
32
|
-
* const myFunction2: VoidGenericFunc<[number, string]> = (a,b) => { console.log(a,b) }; // a is a number, b is a string
|
|
33
|
-
*/
|
|
34
|
-
type VoidGenericFunc<T = unknown> = GenericFunc<T, void>;
|
|
35
|
-
/**
|
|
36
|
-
* Helper for declaring a function that returns a boolean easly. This is usually painful because of the argument spreading
|
|
37
|
-
* @example
|
|
38
|
-
* const myFunction: BooleanGetter<number> = (a) => a > 0 // a is a number
|
|
39
|
-
* const myFunction2: BooleanGetter<[number, string]> = (a,b) => a > 0 && b.length > 0 // a is a number, b is a string
|
|
40
|
-
*/
|
|
41
|
-
type BooleanGetter<T = unknown> = GenericFunc<T, boolean>;
|
|
42
|
-
/** ***************************************************************************
|
|
43
|
-
* Debugging Helpers
|
|
44
|
-
**************************************************************************** */
|
|
45
|
-
/**
|
|
46
|
-
* debugging helper to show the expanded typescript contract,
|
|
47
|
-
* it's only useful to debug, it's NOT MEANT to be used for actual declarations
|
|
48
|
-
* using this for actual declarations will cause the types to be slow to compile/resolve and would have no benefit.
|
|
49
|
-
* https://stackoverflow.com/questions/57683303/how-can-i-see-the-full-expanded-contract-of-a-typescript-type
|
|
50
|
-
* @example
|
|
51
|
-
* type Decorated = {
|
|
52
|
-
* a?: string | null
|
|
53
|
-
* b?: T2
|
|
54
|
-
* c?: T1
|
|
55
|
-
* d: string
|
|
56
|
-
* e: number
|
|
57
|
-
* }
|
|
58
|
-
* type Injected = {
|
|
59
|
-
* inj: object
|
|
60
|
-
* }
|
|
61
|
-
* // overriding the types from Decorated
|
|
62
|
-
* type Text = Decorated &
|
|
63
|
-
* Injected & {
|
|
64
|
-
* name: string;
|
|
65
|
-
* type: "text";
|
|
66
|
-
* value: string;
|
|
67
|
-
* subobject: Injected;
|
|
68
|
-
* };
|
|
69
|
-
*
|
|
70
|
-
* type Expanded = DebugExpandT<Text>;
|
|
71
|
-
*/
|
|
72
|
-
type DebugExpandT<T> = T extends (...args: infer A) => infer R ? (...args: DebugExpandT<A>) => DebugExpandT<R> : T extends infer O ? {
|
|
73
|
-
[K in keyof O]: O[K];
|
|
74
|
-
} : never;
|
|
75
|
-
/**
|
|
76
|
-
* debugging helper to show the expanded typescript contract,
|
|
77
|
-
* it's only useful to debug, it's NOT MEANT to be used for actual declarations
|
|
78
|
-
* using this for actual declarations will cause the types to be slow to compile/resolve and would have no benefit.
|
|
79
|
-
* https://stackoverflow.com/questions/57683303/how-can-i-see-the-full-expanded-contract-of-a-typescript-type
|
|
80
|
-
* @example
|
|
81
|
-
* type Decorated = {
|
|
82
|
-
* a?: string | null
|
|
83
|
-
* b?: T2
|
|
84
|
-
* c?: T1
|
|
85
|
-
* d: string
|
|
86
|
-
* e: number
|
|
87
|
-
* }
|
|
88
|
-
* type Injected = {
|
|
89
|
-
* inj: object
|
|
90
|
-
* }
|
|
91
|
-
* // overriding the types from Decorated
|
|
92
|
-
* type Text = Decorated &
|
|
93
|
-
* Injected & {
|
|
94
|
-
* name: string;
|
|
95
|
-
* type: "text";
|
|
96
|
-
* value: string;
|
|
97
|
-
* subobject: Injected;
|
|
98
|
-
* };
|
|
99
|
-
* interface SomeFunction {
|
|
100
|
-
* (...args: Text[]): Injected & { error: boolean };
|
|
101
|
-
* }
|
|
102
|
-
*
|
|
103
|
-
* type ExpandedRecursively = DebugExpandRecursivelyT<Text>;
|
|
104
|
-
*/
|
|
105
|
-
type DebugExpandRecursivelyT<T> = T extends (...args: infer A) => infer R ? (...args: DebugExpandRecursivelyT<A>) => DebugExpandRecursivelyT<R> : T extends object ? T extends infer O ? {
|
|
106
|
-
[K in keyof O]: DebugExpandRecursivelyT<O[K]>;
|
|
107
|
-
} : never : T;
|
|
108
|
-
/** ***************************************************************************
|
|
109
|
-
* React Helpers
|
|
110
|
-
**************************************************************************** */
|
|
111
|
-
/**
|
|
112
|
-
* An helper useful when you need the type of the second return value of React.useState
|
|
113
|
-
* @example
|
|
114
|
-
* const MyComponent = ({ setFoo }:{
|
|
115
|
-
* setFoo: StateSetter<string>; // our children expects a react "state setter"
|
|
116
|
-
* }) => {
|
|
117
|
-
* const handleClick = () => {
|
|
118
|
-
* setFoo('New value');
|
|
119
|
-
* };
|
|
120
|
-
* return <button onClick={handleClick}>Set Foo</button>;
|
|
121
|
-
* };
|
|
122
|
-
* const ParentComponent: React.FC = () => {
|
|
123
|
-
* const [foo, setFoo] = React.useState<string>('Initial value');
|
|
124
|
-
* return (
|
|
125
|
-
* <div>
|
|
126
|
-
* <p>Foo: {foo}</p>
|
|
127
|
-
* <MyComponent setFoo={setFoo} />
|
|
128
|
-
* </div>
|
|
129
|
-
* );
|
|
130
|
-
* };
|
|
131
|
-
*/
|
|
132
|
-
type StateSetter<T = unknown> = React.Dispatch<React.SetStateAction<T>>;
|
|
133
|
-
/**
|
|
134
|
-
* An helper useful when you need to type an higher order component that has no special requirements on the interface of the component it implements
|
|
135
|
-
* @example
|
|
136
|
-
* // a generic component that displays a label and a value for the sake of the example
|
|
137
|
-
* interface LabelValueDisplayerPropsT {
|
|
138
|
-
* foo: string;
|
|
139
|
-
* bar: number;
|
|
140
|
-
* }
|
|
141
|
-
* const LabelValueDisplayer: React.ComponentType<LabelValueDisplayerPropsT> = ({ foo, bar }) => (
|
|
142
|
-
* <div>
|
|
143
|
-
* <label>{foo}</label>
|
|
144
|
-
* <div>{bar}</div>
|
|
145
|
-
* </div>
|
|
146
|
-
* );
|
|
147
|
-
*
|
|
148
|
-
* // we are creating an example HOC that logs the props of the component it wraps before rendering it
|
|
149
|
-
* const withLogging: TypescriptHelpersT.ReactFunctionalHOC<LabelValueDisplayerPropsT> = (Component) => (props) => {
|
|
150
|
-
* console.log('Rendering component with props:', props);
|
|
151
|
-
* return <Component {...props} />;
|
|
152
|
-
* };
|
|
153
|
-
*
|
|
154
|
-
* // we can now use the HOC to wrap our component
|
|
155
|
-
* const ComponentWithGenericLogging = withLogging(LabelValueDisplayer);
|
|
156
|
-
* const ExampleUsageInComponent = () => {
|
|
157
|
-
* return <ComponentWithGenericLogging foo="Test" bar={123} />; // <-- this is correctly typed!
|
|
158
|
-
* };
|
|
159
|
-
*/
|
|
160
|
-
type ReactFunctionalHOC<T = Record<string, unknown>> = (Component: React.ComponentType<JSX.IntrinsicAttributes & T>) => React.ComponentType<JSX.IntrinsicAttributes & T>;
|
|
161
|
-
/**
|
|
162
|
-
* An helper useful when you need to type an higher order component that has special requirements on the interface of the component it implements
|
|
163
|
-
* @example
|
|
164
|
-
* // a generic component that displays a label and a value for the sake of the example
|
|
165
|
-
* interface LabelValueDisplayerPropsT {
|
|
166
|
-
* foo: string;
|
|
167
|
-
* bar: number;
|
|
168
|
-
* }
|
|
169
|
-
* const LabelValueDisplayer: React.ComponentType<LabelValueDisplayerPropsT> = ({ foo, bar }) => (
|
|
170
|
-
* <div>
|
|
171
|
-
* <label>{foo}</label>
|
|
172
|
-
* <div>{bar}</div>
|
|
173
|
-
* </div>
|
|
174
|
-
* );
|
|
175
|
-
*
|
|
176
|
-
* interface LoggerProps { loggableTemplateLabel: string; loggableTemplateValue: string; }
|
|
177
|
-
*
|
|
178
|
-
* // the HOC we are creating has special requirements on the props of the component it wraps
|
|
179
|
-
* // AND it has some requirements on it's own props
|
|
180
|
-
* const withLogging: ReactFunctionalHOCWithDifferentInterface<LoggerProps, StartingProps> =
|
|
181
|
-
* (Component) => ({ loggableTemplateLabel, loggableTemplateValue }) => {
|
|
182
|
-
* const startingLabel = loggableTemplateLabel.replace(/{{label was}}/g, "");
|
|
183
|
-
* const startingValue = parseInt(
|
|
184
|
-
* loggableTemplateValue.replace(/{{value was}}/g, ""),
|
|
185
|
-
* 10
|
|
186
|
-
* );
|
|
187
|
-
* console.log(
|
|
188
|
-
* `${loggableTemplateLabel.replace(/{{label was}}/g, "Label was -> ")}`,
|
|
189
|
-
* `${loggableTemplateValue.replace(/{{value was}}/g, "Value was -> ")}`
|
|
190
|
-
* );
|
|
191
|
-
* return <Component startA={startingLabel} startB={startingValue} />;
|
|
192
|
-
* };
|
|
193
|
-
*
|
|
194
|
-
* const ComponentWithSpecialLogging = withLogging(LabelValueDisplayer); // <-- this is correctly typed!
|
|
195
|
-
* const ExampleUsageInComponent = () => (
|
|
196
|
-
* <ComponentWithSpecialLogging
|
|
197
|
-
* loggableTemplateLabel="{{label was}}Starting count:"
|
|
198
|
-
* loggableTemplateValue="{{value was}}0"
|
|
199
|
-
* />
|
|
200
|
-
* )
|
|
201
|
-
*/
|
|
202
|
-
type ReactFunctionalHOCWithDifferentInterface<K = Record<string, unknown>, T = Record<string, unknown>> = (Component: React.ComponentType<JSX.IntrinsicAttributes & T>) => React.ComponentType<K>;
|
|
203
|
-
/**
|
|
204
|
-
* An helper for declaring the return type of React.useRef in a way that reflects the reality of how it can be used
|
|
205
|
-
* @example
|
|
206
|
-
* const ComponentWithRef = () => {
|
|
207
|
-
* // starting value for ref should be null
|
|
208
|
-
* const myRef: T.AnyRef<HTMLDivElement> = React.useRef<HTMLDivElement>(null);
|
|
209
|
-
* return (<div ref={
|
|
210
|
-
* (node => {
|
|
211
|
-
* // when used it should reflect what you can actually do with it, mutating it is valid.
|
|
212
|
-
* myRef.current = node;
|
|
213
|
-
* })
|
|
214
|
-
* }>Hello, world!</div>)
|
|
215
|
-
* };
|
|
216
|
-
*/
|
|
217
|
-
type AnyRef<T> = React.MutableRefObject<T | null> | ((_ref: T | null) => void);
|
|
218
|
-
/**
|
|
219
|
-
* An helper for defining the type of the children prop of a React component
|
|
220
|
-
* @example
|
|
221
|
-
* type ReactChildrenComplete = React.PropsWithChildren<object>["children"];
|
|
222
|
-
* type MyComponentProps = {
|
|
223
|
-
* children: ReactChildrenComplete;
|
|
224
|
-
* foo: string;
|
|
225
|
-
* };
|
|
226
|
-
* const MyComponent = ({ children, foo }: MyComponentProps) => ( <div>{children}{foo}</div> );
|
|
227
|
-
*/
|
|
228
|
-
type ReactChildrenComplete = React.PropsWithChildren<object>['children'];
|
|
229
|
-
/** ***************************************************************************
|
|
230
|
-
* Object Helpers
|
|
231
|
-
**************************************************************************** */
|
|
232
|
-
/**
|
|
233
|
-
* Helper to declare an object that has at least one of the keys of the original object as required
|
|
234
|
-
* https://www.typescriptlang.org/play?#code/C4TwDgpgBAShCOBXAlgJwgQWAGQgQwGdgB5AOwgB4AVAGigGkIQCoIAPYCUgExYGsmAewBmUKlAC8UASBFiAfJICwAKCjqoABWQBjPtToBRNjoA2ibpRlzaDJgXnzVGqADIoAb2cuNAbXpQyKR2zAC6ALQA-ABcsAgo6NwU2noGDI5uWniowMh4psm6+rbGZhaUjMx09I5OahoAvv72oaqqQZyowng60ACyXIgAkpwAtp7eucCmELFEqEEA5gDc3jqCo2CC5KTAMVCkiKMARhCoq-VmRfuHJ2cX6rrbc8ALpCuqDW0qoJBQAMKmIrEVD-DZbHbASRxJBoTA4fBEMiUAaHEYQUZ0ADkVz0WKgAB8oDjwdsuMAsXVVOtSEQoAB3ZDAAAWYM2ZN2sUBwNBpMh0K89XUUxmsQARJwiGKaN51Ot2ZDYgBWABMMqFgRp4qepDFn2+NLpjJZ3L0XKBehBbIh5IFsqgItmUAlECl6pcuL4yoALO6NDrtTS9Sovipqds6WdUIJUAB1JnMgByEATZ3NPOtHKhUkFLkd4slwGl9oDzp1wdD4dpUNIgkMqGjcYTACFBCz05beQrbTn7fnnYXixrPT6-XK+eTYirfSWtWWg-qwypDVCozH4yzWyzY8yuMiABKEWPR95UcBO018K0T3Z2jX9l1u+0jqBKmfDm-AcUEZmCRCmbgoFOA4jlOVAoF3dAhxcUsxXLRdvl+aA4FhdAyFMEBkTSSoWHYTgeH4IRRHEKRrGIxQJHtFJiiMExzEsCgyLEap7Ece13A8KB-ECYIcIiGJ7RcFCEggJJqOwtiNRcdxNGyXJ8goOB1lQJJSnoip7GqeQ6EQHgIGEIJRMklwmj4xDzygdDMPIS9r27W8pGEuErKw1FhjGbFPXxIkSXsikqWXCMazrBt1wTFzyFiCKIFsrsbQciZ7yZUUB1dIsxygF8lQAZnfGC5zghcQwNILWFCptNzbZkotIDDkVizN+V7JLpidR90ufC0vVfXKMvleKvx6jLYPg4ql1UAB6CaxGZZAWA6M5ul6BlkFMUwgOgRACFEh1BAdBY9Es2rrJirqsEa20Oj2-JTEERl3igPBgkEY4ACsIB0KFjWZICqvUdpdkWnpoEvNz0XGXMHWSp15iWB5Mq62JbjA+HS1h94LkrQLqwgwgtx+5q82hgs0ugjQsry8nPynSnHgK0asamqBEz2tdwNOHQ8C26B2F6AgWDAaNIByZBXUe9AoG2DCoG4Oabrunb6V3YJZfQT7pcIAhkEWUglke563o+qEgU6fIoCrOkxjADs+DBsZoWZPGqu+JmWbKxsZddMAmWgK3Hs+xAbpAXGADc9eOP6Oa57axAAZUl47pFrekWBZPAoT9ubHoBLq7Yxc3sctg6+CGXZBAwNa7qWfGarqmyursgboSt1QgA
|
|
235
|
-
* @example
|
|
236
|
-
* const myObject: RequireAtLeastOne<{a: string, b: string}> = {a: 'foo'}; // valid
|
|
237
|
-
* const myObject2: RequireAtLeastOne<{a: string, b: string}> = {b: 'foo'}; // valid
|
|
238
|
-
* const myObject3: RequireAtLeastOne<{a: string, b: string}> = {a: 'foo', b: 'bar'}; // valid
|
|
239
|
-
*
|
|
240
|
-
* const myObject4: RequireAtLeastOne<{a: string, b: string}> = {}; // invalid
|
|
241
|
-
*/
|
|
242
|
-
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
|
|
243
|
-
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
244
|
-
}[Keys];
|
|
245
|
-
/**
|
|
246
|
-
* Helper to declare an object that has only one of the keys of the original object as required
|
|
247
|
-
* @example
|
|
248
|
-
* const myObject: RequireOnlyOne<{a: string, b: string}> = {a: 'foo'}; // valid
|
|
249
|
-
* const myObject2: RequireOnlyOne<{a: string, b: string}> = {b: 'foo'}; // valid
|
|
250
|
-
*
|
|
251
|
-
* const myObject3: RequireOnlyOne<{a: string, b: string}> = {a: 'foo', b: 'bar'}; // invalid
|
|
252
|
-
*/
|
|
253
|
-
type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
|
|
254
|
-
[K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>;
|
|
255
|
-
}[Keys];
|
|
256
|
-
/**
|
|
257
|
-
* An Helper that given the type of an object, returns the type of the values of the object
|
|
258
|
-
*
|
|
259
|
-
* This is an useful alternative to typescripts enums, making your code as type safe as enums but without the typescript exclusive declaration and syntax
|
|
260
|
-
*
|
|
261
|
-
* Projects are free to decide wheter or not they wish to allow enums in their code base but we suggest being aware of the pitfalls of enums and double check the official documentation before making a decision
|
|
262
|
-
*
|
|
263
|
-
* https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums
|
|
264
|
-
*
|
|
265
|
-
* > The biggest argument in favour of this format over TypeScript's enum is that it keeps your codebase aligned with the state of JavaScript, and when/if enums are added to JavaScript then you can move to the additional syntax.
|
|
266
|
-
*
|
|
267
|
-
* https://github.com/tc39/proposal-type-annotations?tab=readme-ov-file#intentional-omissions
|
|
268
|
-
* @example
|
|
269
|
-
* type MyObject = {a: string, b: number};
|
|
270
|
-
* type MyObjectValues = ObjectValues<MyObject>; // MyObjectValues = string | number
|
|
271
|
-
* @example
|
|
272
|
-
* const myEnumLikeObject = {
|
|
273
|
-
* a: 'foo',
|
|
274
|
-
* b: 'bar'
|
|
275
|
-
* } as const;
|
|
276
|
-
*
|
|
277
|
-
* type myEnumLikeObjectValues = TypescriptHelpersT.ObjectValues<typeof myEnumLikeObject>; // myEnumLikeObjectValues = 'foo' | 'bar'
|
|
278
|
-
* const foo: myEnumLikeObjectValues = 'foo'; // valid
|
|
279
|
-
* const foo2: myEnumLikeObjectValues = 'bar'; // valid
|
|
280
|
-
*
|
|
281
|
-
* const foo3: myEnumLikeObjectValues = 'baz'; // invalid
|
|
282
|
-
*/
|
|
283
|
-
type ObjectValues<T> = T[keyof T];
|
|
284
|
-
/**
|
|
285
|
-
* A type that represents an object in which every key starts with "data-" and the value is a string, useful for declaring the data-* attributes of an HTML element
|
|
286
|
-
* @example
|
|
287
|
-
* const myObject: DataProps = { 'data-foo': 'bar' }; // valid
|
|
288
|
-
*
|
|
289
|
-
* const myObject2: DataProps = { 'aria-foo': 123 }; // invalid
|
|
290
|
-
* const myObject3: DataProps = { 'foo': 'bar' }; // invalid
|
|
291
|
-
*/
|
|
292
|
-
type DataProps = {
|
|
293
|
-
[key in `data-${string}`]: string;
|
|
294
|
-
};
|
|
295
|
-
/**
|
|
296
|
-
* A type that represents an object in which every key starts with "aria-" and the value is a string, useful for declaring the aria-* attributes of an HTML element
|
|
297
|
-
* @example
|
|
298
|
-
* const myObject: AriaProps = { 'aria-foo': 'bar' }; // valid
|
|
299
|
-
*
|
|
300
|
-
* const myObject2: AriaProps = { 'data-foo': 123 }; // invalid
|
|
301
|
-
* const myObject3: AriaProps = { 'foo': 'bar' }; // invalid
|
|
302
|
-
*/
|
|
303
|
-
type AriaProps = {
|
|
304
|
-
[key in `aria-${string}`]: string;
|
|
305
|
-
};
|
|
306
|
-
/**
|
|
307
|
-
* A type that represents an object in which every key starts with "data-" or "aria-" and the value is a string, useful for declaring the aria-* and data-* attributes of an HTML element
|
|
308
|
-
* @example
|
|
309
|
-
* const myObject: AriaAndDataProps = { 'aria-foo': 'bar' }; // valid
|
|
310
|
-
* const myObject2: AriaAndDataProps = { 'data-foo': 'bar' }; // valid
|
|
311
|
-
* const myObject3: AriaAndDataProps = { 'aria-foo': 'bar', 'data-foo': 'bar' }; // valid
|
|
312
|
-
*
|
|
313
|
-
* const myObject4: AriaAndDataProps = { 'foo': 'bar' }; // invalid
|
|
314
|
-
*/
|
|
315
|
-
type AriaAndDataProps = {
|
|
316
|
-
[key in `data-${string}` | `aria-${string}`]: string;
|
|
317
|
-
};
|
|
318
|
-
/**
|
|
319
|
-
* Type helper that excludes keys from one type that exist in another.
|
|
320
|
-
* @example
|
|
321
|
-
* type MyType = ExcludeKeys<{a: string, b: number}, {a: string}>; // MyType = {b: number}
|
|
322
|
-
* type MyType2 = ExcludeKeys<{a: string, b: number}, {a: string, b: number}>; // MyType2 = {}
|
|
323
|
-
* type MyType3 = ExcludeKeys<{a: string, b: number}, {c: string}>; // MyType3 = {a: string, b: number}
|
|
324
|
-
*/
|
|
325
|
-
type ExcludeKeys<T, U> = {
|
|
326
|
-
[K in keyof T as K extends keyof U ? never : K]: T[K];
|
|
327
|
-
};
|
|
328
|
-
/** ***************************************************************************
|
|
329
|
-
* Template Literals
|
|
330
|
-
* Snake, Camel, Pascal, Kebab Case
|
|
331
|
-
* https://stackoverflow.com/questions/60269936/typescript-convert-generic-object-from-snake-to-camel-case
|
|
332
|
-
* https://www.typescriptlang.org/play?#code/C4TwDgpgBAygdgQwNYQCoHsDCCC2EA22AzhADwxQQAewEcAJkVEcAE4CWcA5gHxQC8AKCixKNOoygADACQBvTgDMIrKKgC+AfXlKVUAKrqpUAPzDp8jfOxh2wBPnYAvMvGRosuAsTL6ePIygALnMYQUFQSChsPHwMNxQfcjFaBiYWDm4+IREKalTJWQU4ZVUrYtKDQLMRItQUiSYbOwdnMlQ+EygAIk1u4J7u9XkAGXQAdxUAYwQSUg7huRiCeMRE2d8A4xDc8MjoZbj0AAVZmcIN5PzG5jZOXgFohFt7RxdyHgjwaFOic4xDkk8uI0rdMg9+AY4DMXq13jBPvsoL9-ugEhAgQ1QRl7tknrFVu4kvpoc8Wm9XP4vlF0RgUQ5MddsXcso9mq82uQ1h5AZcEZ9qdAANIQABGCFFhPWc2BBXSLIhoSxhR0JT0GgAtKrKoZjDULHINNo5CLxZK0dziVtgqE9t8oAA5R4AFgATHaoqgkABGb2PU0SqUYy7dAAWBHw6G6fAA9DGeuH8JHNON0Kx8PRuoK1D7Xf6xYGLUSQ4nIxrU6xM7H42GI+gU2mM1mkV7vQBmfNmoNJWtJ9DltP0DW0FjRqBxhN1hvp+iaEfAZv21vOzuF9E90v9itD+f9AA+UAA5Ip0P3xaxhxAWIfq5O+9PZ7uoAfuif6+e51eF9nWwBWVfmuulw4qyE4gVwP4+gAbAB3aXFIwDhhqCBwEQkwXuwRBanIDpGLe3SIRAmgoWhKiaJhmhuv0AAUSJOpCboAJQetAqC+o8tKeLEG51mOE69pGi6et6eaQpxvJzAJ9YVk2+GbgA6o2mY-u2HHcgCXgXJJm5zkQ06yeONabqgRCKTOQmsd6K5iepXHeCWU4yZmz49G+mjnnxRl1mZTYua+p4AEIIKwFlqN6-42e4GnccBCq3uBKkwZFKDRfZcwIeGxGoeh5F6fIuFSPhhEAILZSoACSRBUVAtH2vRUBMSxaiun6kKHHB2m8XJvE-q6on4isRbSmQUk+VWhl3smTmhagrodm1mkdSNxmmUpnmTfWwB6dNTWoG2rUDUc9JactXU-m2-XtScZwMg5fZjdG53zYddI3SdpBSSZD0Ci2zoHZxx08X2j2-f1ANvUDU1rYiS7Os94N-LdnX3lt+lVrtv4HcdqXvd0AASZ0tr+-XY3ZuME-d0M-r+z2kxJI0U5GX1Uz+UFY29S0fYzUYw56UEkxzQ3BpJ3PfaztOC0BIt1sz5k-fa5VwGAACuwCoPakJyOYRDcpoMwkJoKAgJo3pBFAcDKzgooqAANNruv60RRuaK6ZvgXb6hNQA8qrKtqxrUByFAADaQpQJwUBG+gihQIrfvq1EsywLZ9OkEKPAALpm3HqsJxAocZ1AnsxgAVOYSI+8A8cB1rIh18wlobCKICm+blvW6wADc5j1zrxYkM3rtgvc3ciJ7JcxuEpdl1AJdQMIc8AKIgkQ7DoHAZuYOvABuKjAObX4QPQUBgKw6CQKwwDsFeC-z7Pk9Ijn-uQA6h-H5r9vuHrGyGxAxut7XOufcUDfwNs7X0bsFQ9wbl-R2v9-5DwSmPO2IhgFETgc7RBCoPZNXEppHwr8WBH3mHieoTJJDoFFAAKwgFMfeXRAGh3DnASOf9o5qCgEnPBMU5hhwAGTDyyFnZOUUyYELfvMAunx1ADFQN7X2udviENoO-ERKUxEbGUcQp+ectH0B4EAA
|
|
333
|
-
**************************************************************************** */
|
|
334
|
-
/**
|
|
335
|
-
* Converts a string from snake_case to camelCase
|
|
336
|
-
* @example
|
|
337
|
-
* type MyType = SnakeToCamelCase<'foo_bar'>; // MyType = 'fooBar'
|
|
338
|
-
*/
|
|
339
|
-
type SnakeToCamelCase<S extends string> = S extends `${infer T}_${infer U}` ? `${T}${Capitalize<SnakeToCamelCase<U>>}` : S;
|
|
340
|
-
/**
|
|
341
|
-
* Converts a string from snake_case to PascalCase
|
|
342
|
-
* @example
|
|
343
|
-
* type MyType = SnakeToPascalCase<'foo_bar'>; // MyType = 'FooBar'
|
|
344
|
-
*/
|
|
345
|
-
type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}` ? `${T extends Capitalize<T> ? '_' : ''}${Lowercase<T>}${CamelToSnakeCase<U>}` : S;
|
|
346
|
-
/**
|
|
347
|
-
* Converts a string from kebab-case to snake_case
|
|
348
|
-
* @example
|
|
349
|
-
* type MyType = KebabToSnakeCase<'foo-bar'>; // MyType = 'foo_bar'
|
|
350
|
-
*/
|
|
351
|
-
type KebabToSnakeCase<S extends string> = S extends `${infer T}-${infer U}` ? `${T}_${KebabToSnakeCase<U>}` : S;
|
|
352
|
-
/**
|
|
353
|
-
* Converts a string from snake_case to kebab-case
|
|
354
|
-
* @example
|
|
355
|
-
* type MyType = SnakeToKebabCase<'foo_bar'>; // MyType = 'foo-bar'
|
|
356
|
-
*/
|
|
357
|
-
type SnakeToKebabCase<S extends string> = S extends `${infer T}_${infer U}` ? `${T}-${SnakeToKebabCase<U>}` : S;
|
|
358
|
-
/**
|
|
359
|
-
* Converts a string from camelCase to PascalCase
|
|
360
|
-
* @example
|
|
361
|
-
* type MyType = CamelToPascalCase<'fooBar'>; // MyType = 'FooBar'
|
|
362
|
-
*/
|
|
363
|
-
type CamelToPascalCase<S extends string> = Capitalize<S>;
|
|
364
|
-
/**
|
|
365
|
-
* Converts a string from PascalCase to camelCase
|
|
366
|
-
* @example
|
|
367
|
-
* type MyType = PascalToCamelCase<'FooBar'>; // MyType = 'fooBar'
|
|
368
|
-
*/
|
|
369
|
-
type PascalToCamelCase<S extends string> = Uncapitalize<S>;
|
|
370
|
-
/**
|
|
371
|
-
* Converts a string from PascalCase to snake_case
|
|
372
|
-
* @example
|
|
373
|
-
* type MyType = PascalToSnakeCase<'FooBar'>; // MyType = 'foo_bar'
|
|
374
|
-
*/
|
|
375
|
-
type PascalToSnakeCase<S extends string> = CamelToSnakeCase<Uncapitalize<S>>;
|
|
376
|
-
/**
|
|
377
|
-
* Converts a string from snake_case to PascalCase
|
|
378
|
-
* @example
|
|
379
|
-
* type MyType = SnakeToPascalCase<'foo_bar'>; // MyType = 'FooBar'
|
|
380
|
-
*/
|
|
381
|
-
type SnakeToPascalCase<S extends string> = Capitalize<SnakeToCamelCase<S>>;
|
|
382
|
-
/** ***************************************************************************
|
|
383
|
-
* Template Literals
|
|
384
|
-
* Dimsum specific (internal) helpers
|
|
385
|
-
****************************************************************************
|
|
386
|
-
*/
|
|
387
|
-
type RemoveDSPrefix<S extends string> = S extends `DS${infer T}` ? T : S;
|
|
388
|
-
type PropsForGlobalOnSlots<Name extends string, Slots extends Record<string, string>> = {
|
|
389
|
-
[key in ObjectValues<Slots> as `ds${RemoveDSPrefix<Name>}${SnakeToPascalCase<KebabToSnakeCase<key>>}`]?: object | ((arg: object) => object);
|
|
390
|
-
};
|
|
391
|
-
type AriaAndDataPropsOrPropsGetter = AriaAndDataProps | (() => AriaAndDataProps);
|
|
392
|
-
type Hydraters<T, Args = unknown> = {
|
|
393
|
-
[key in keyof T as key extends string ? `get${Capitalize<key>}` : key]: (...args: Args extends Array<unknown> ? Args : Args[]) => T[key];
|
|
394
|
-
};
|
|
395
|
-
}
|