uni-types 1.0.0-beta.0 → 1.0.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/LICENSE +21 -0
- package/README.md +304 -0
- package/dist/index.d.cts +547 -0
- package/dist/index.d.mts +547 -0
- package/dist/index.mjs +1 -0
- package/package.json +78 -13
- /package/{index.js → dist/index.cjs} +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 saqqdy <saqqdy@qq.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
<div style="text-align: center;" align="center">
|
|
2
|
+
|
|
3
|
+
# uni-types
|
|
4
|
+
|
|
5
|
+
Universal TypeScript type utilities - A comprehensive collection of type helpers for TypeScript development
|
|
6
|
+
|
|
7
|
+
English | [简体中文](./README_CN.md)
|
|
8
|
+
|
|
9
|
+
[![NPM version][npm-image]][npm-url]
|
|
10
|
+
![typescript][typescript-url]
|
|
11
|
+
[![Test coverage][codecov-image]][codecov-url]
|
|
12
|
+
[![npm download][download-image]][download-url]
|
|
13
|
+
[![License][license-image]][license-url]
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# use pnpm
|
|
21
|
+
$ pnpm add uni-types
|
|
22
|
+
|
|
23
|
+
# use yarn
|
|
24
|
+
$ yarn add uni-types
|
|
25
|
+
|
|
26
|
+
# use npm
|
|
27
|
+
$ npm install uni-types
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import type { PickRequired, DeepPartial, IsArray } from 'uni-types'
|
|
34
|
+
|
|
35
|
+
// Use in your TypeScript projects
|
|
36
|
+
interface User {
|
|
37
|
+
name?: string
|
|
38
|
+
age?: number
|
|
39
|
+
email: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type RequiredNameUser = PickRequired<User, 'name'>
|
|
43
|
+
// { name: string; age?: number; email: string }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API Reference
|
|
47
|
+
|
|
48
|
+
### Core Operations
|
|
49
|
+
|
|
50
|
+
| Type | Description |
|
|
51
|
+
|------|-------------|
|
|
52
|
+
| `PickRequired<T, K>` | Make specified properties required |
|
|
53
|
+
| `OmitRequired<T, K>` | Make properties except specified ones required |
|
|
54
|
+
| `PickPartial<T, K>` | Make specified properties optional |
|
|
55
|
+
| `OmitPartial<T, K>` | Make properties except specified ones optional |
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
interface User {
|
|
59
|
+
name?: string
|
|
60
|
+
age?: number
|
|
61
|
+
email: string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
PickRequired<User, 'name'> // { name: string; age?: number; email: string }
|
|
65
|
+
OmitRequired<User, 'name'> // { name?: string; age: number; email: string }
|
|
66
|
+
PickPartial<User, 'email'> // { name?: string; age?: number; email?: string }
|
|
67
|
+
OmitPartial<User, 'email'> // { name: string; age: number; email?: string }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Tuple Operations
|
|
71
|
+
|
|
72
|
+
| Type | Description |
|
|
73
|
+
|------|-------------|
|
|
74
|
+
| `Head<T>` | Get first element of tuple |
|
|
75
|
+
| `Last<T>` | Get last element of tuple |
|
|
76
|
+
| `Tail<T>` | Get all elements except first |
|
|
77
|
+
| `Init<T>` | Get all elements except last |
|
|
78
|
+
| `Reverse<T>` | Reverse a tuple |
|
|
79
|
+
| `Flatten<T>` | Flatten nested tuples |
|
|
80
|
+
| `TupleLength<T>` | Get tuple length |
|
|
81
|
+
| `IsEmptyTuple<T>` | Check if tuple is empty |
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
Head<[1, 2, 3]> // 1
|
|
85
|
+
Last<[1, 2, 3]> // 3
|
|
86
|
+
Tail<[1, 2, 3]> // [2, 3]
|
|
87
|
+
Init<[1, 2, 3]> // [1, 2]
|
|
88
|
+
Reverse<[1, 2, 3]> // [3, 2, 1]
|
|
89
|
+
Flatten<[1, [2, [3]]]> // [1, 2, 3]
|
|
90
|
+
TupleLength<[1, 2, 3]> // 3
|
|
91
|
+
IsEmptyTuple<[]> // true
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Deep Operations
|
|
95
|
+
|
|
96
|
+
| Type | Description |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `DeepPartial<T>` | Make all nested properties optional |
|
|
99
|
+
| `DeepRequired<T>` | Make all nested properties required |
|
|
100
|
+
| `DeepReadonly<T>` | Make all nested properties readonly |
|
|
101
|
+
| `DeepMutable<T>` | Make all nested properties mutable |
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
interface Nested {
|
|
105
|
+
a: { b: { c: string } }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
DeepPartial<Nested> // { a?: { b?: { c?: string } } }
|
|
109
|
+
DeepRequired<{ a?: { b?: string } }> // { a: { b: string } }
|
|
110
|
+
DeepReadonly<Nested> // { readonly a: { readonly b: { readonly c: string } } }
|
|
111
|
+
DeepMutable<{ readonly a: { readonly b: string } }> // { a: { b: string } }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Type Guards
|
|
115
|
+
|
|
116
|
+
| Type | Description |
|
|
117
|
+
|------|-------------|
|
|
118
|
+
| `IsArray<T>` | Check if type is an array |
|
|
119
|
+
| `IsTuple<T>` | Check if type is a tuple |
|
|
120
|
+
| `IsEqual<X, Y>` | Check if two types are equal |
|
|
121
|
+
| `IsAny<T>` | Check if type is `any` |
|
|
122
|
+
| `IsNever<T>` | Check if type is `never` |
|
|
123
|
+
| `IsUnknown<T>` | Check if type is `unknown` |
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
IsArray<string[]> // true
|
|
127
|
+
IsArray<string> // false
|
|
128
|
+
IsTuple<[string, number]> // true
|
|
129
|
+
IsTuple<string[]> // false
|
|
130
|
+
IsEqual<string, string> // true
|
|
131
|
+
IsEqual<string, number> // false
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Type Inference
|
|
135
|
+
|
|
136
|
+
| Type | Description |
|
|
137
|
+
|------|-------------|
|
|
138
|
+
| `Awaited<T>` | Unwrap Promise type recursively |
|
|
139
|
+
| `ArrayElement<T>` | Get array element type |
|
|
140
|
+
| `ValueOf<T>` | Get object value types |
|
|
141
|
+
| `FunctionKeys<T>` | Get keys of function properties |
|
|
142
|
+
| `NonFunctionKeys<T>` | Get keys of non-function properties |
|
|
143
|
+
| `FirstParameter<T>` | Get first parameter type of function |
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
Awaited<Promise<string>> // string
|
|
147
|
+
Awaited<Promise<Promise<number>>> // number
|
|
148
|
+
ArrayElement<string[]> // string
|
|
149
|
+
ValueOf<{ a: string; b: number }> // string | number
|
|
150
|
+
FunctionKeys<{ name: string; onClick: () => void }> // 'onClick'
|
|
151
|
+
NonFunctionKeys<{ name: string; onClick: () => void }> // 'name'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Utility Types
|
|
155
|
+
|
|
156
|
+
| Type | Description |
|
|
157
|
+
|------|-------------|
|
|
158
|
+
| `Merge<T, U>` | Merge two types (U overrides T) |
|
|
159
|
+
| `NonNullable<T>` | Exclude `null` and `undefined` |
|
|
160
|
+
| `Exclusive<T, K>` | Create mutually exclusive properties |
|
|
161
|
+
| `NoNullish<T>` | Remove null/undefined from all properties |
|
|
162
|
+
| `Nullable<T>` | Add `null` to type |
|
|
163
|
+
| `Optional<T>` | Add `undefined` to type |
|
|
164
|
+
| `Maybe<T>` | Add `null` and `undefined` to type |
|
|
165
|
+
| `LoosePartial<T>` | Make all properties optional |
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
Merge<{ a: string; b: number }, { b: boolean; c: string }>
|
|
169
|
+
// { a: string; b: boolean; c: string }
|
|
170
|
+
|
|
171
|
+
NonNullable<string | null | undefined> // string
|
|
172
|
+
Nullable<string> // string | null
|
|
173
|
+
Optional<string> // string | undefined
|
|
174
|
+
Maybe<string> // string | null | undefined
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Key Types
|
|
178
|
+
|
|
179
|
+
| Type | Description |
|
|
180
|
+
|------|-------------|
|
|
181
|
+
| `RequiredKeys<T>` | Get all required property keys |
|
|
182
|
+
| `OptionalKeys<T>` | Get all optional property keys |
|
|
183
|
+
| `WritableKeys<T>` | Get all writable (non-readonly) keys |
|
|
184
|
+
| `ReadonlyKeys<T>` | Get all readonly keys |
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
interface User {
|
|
188
|
+
name: string
|
|
189
|
+
age?: number
|
|
190
|
+
readonly id: number
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
RequiredKeys<User> // 'name'
|
|
194
|
+
OptionalKeys<User> // 'age'
|
|
195
|
+
WritableKeys<User> // 'name' | 'age'
|
|
196
|
+
ReadonlyKeys<User> // 'id'
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Path Types
|
|
200
|
+
|
|
201
|
+
| Type | Description |
|
|
202
|
+
|------|-------------|
|
|
203
|
+
| `Paths<T>` | Get all nested property paths |
|
|
204
|
+
| `PathValue<T, P>` | Get value type at path |
|
|
205
|
+
| `SplitPath<S>` | Split path string into array |
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
interface Obj {
|
|
209
|
+
a: { b: { c: string } }
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Paths<Obj> // 'a' | 'a.b' | 'a.b.c'
|
|
213
|
+
PathValue<Obj, 'a.b'> // { c: string }
|
|
214
|
+
SplitPath<'a.b.c'> // ['a', 'b', 'c']
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Literal Types
|
|
218
|
+
|
|
219
|
+
| Type | Description |
|
|
220
|
+
|------|-------------|
|
|
221
|
+
| `Literal` | All literal types union |
|
|
222
|
+
| `LiteralString<T>` | Exact string literal |
|
|
223
|
+
| `LiteralNumber<T>` | Exact number literal |
|
|
224
|
+
| `LiteralBoolean<T>` | Exact boolean literal |
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
Literal // string | number | boolean | undefined | null | void | bigint
|
|
228
|
+
LiteralString<'hello'> // 'hello'
|
|
229
|
+
LiteralNumber<42> // 42
|
|
230
|
+
LiteralBoolean<true> // true
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### String Case Conversion
|
|
234
|
+
|
|
235
|
+
| Type | Description |
|
|
236
|
+
|------|-------------|
|
|
237
|
+
| `CamelCase<S>` | Convert to camelCase |
|
|
238
|
+
| `SnakeCase<S>` | Convert to snake_case |
|
|
239
|
+
| `CamelCaseKeys<T>` | Convert object keys to camelCase |
|
|
240
|
+
| `SnakeCaseKeys<T>` | Convert object keys to snake_case |
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
CamelCase<'hello_world'> // 'helloWorld'
|
|
244
|
+
CamelCase<'foo-bar-baz'> // 'fooBarBaz'
|
|
245
|
+
SnakeCase<'helloWorld'> // 'hello_world'
|
|
246
|
+
SnakeCase<'XMLParser'> // 'xml_parser'
|
|
247
|
+
CamelCaseKeys<{ hello_world: string }> // { helloWorld: string }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Advanced Types
|
|
251
|
+
|
|
252
|
+
| Type | Description |
|
|
253
|
+
|------|-------------|
|
|
254
|
+
| `FunctionOnly<T>` | Extract only function properties |
|
|
255
|
+
| `DataOnly<T>` | Extract only non-function properties |
|
|
256
|
+
| `AtLeastOne<T>` | Require at least one property |
|
|
257
|
+
| `StrictExtract<T, U>` | Strictly extract matching types |
|
|
258
|
+
| `StrictExclude<T, U>` | Strictly exclude types |
|
|
259
|
+
| `UnionToIntersection<U>` | Convert union to intersection |
|
|
260
|
+
| `UnionToTuple<T>` | Convert union to tuple |
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
interface Obj { name: string; onClick: () => void }
|
|
264
|
+
FunctionOnly<Obj> // { onClick: () => void }
|
|
265
|
+
DataOnly<Obj> // { name: string }
|
|
266
|
+
|
|
267
|
+
UnionToIntersection<{ a: string } | { b: number }> // { a: string } & { b: number }
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Development
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Install dependencies
|
|
274
|
+
pnpm install
|
|
275
|
+
|
|
276
|
+
# Build
|
|
277
|
+
pnpm build
|
|
278
|
+
|
|
279
|
+
# Test
|
|
280
|
+
pnpm test
|
|
281
|
+
|
|
282
|
+
# Test with coverage
|
|
283
|
+
pnpm test:coverage
|
|
284
|
+
|
|
285
|
+
# Type check
|
|
286
|
+
pnpm typecheck
|
|
287
|
+
|
|
288
|
+
# Lint
|
|
289
|
+
pnpm lint
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
[MIT](LICENSE)
|
|
295
|
+
|
|
296
|
+
[npm-image]: https://img.shields.io/npm/v/uni-types.svg?style=flat-square
|
|
297
|
+
[npm-url]: https://npmjs.org/package/uni-types
|
|
298
|
+
[typescript-url]: https://badgen.net/badge/icon/typescript?icon=typescript&label
|
|
299
|
+
[codecov-image]: https://img.shields.io/codecov/c/github/saqqdy/uni-types.svg?style=flat-square
|
|
300
|
+
[codecov-url]: https://codecov.io/github/saqqdy/uni-types?branch=master
|
|
301
|
+
[download-image]: https://img.shields.io/npm/dm/uni-types.svg?style=flat-square
|
|
302
|
+
[download-url]: https://npmjs.org/package/uni-types
|
|
303
|
+
[license-image]: https://img.shields.io/badge/License-MIT-blue.svg
|
|
304
|
+
[license-url]: LICENSE
|