smart-result 0.0.1
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/CHANGELOG.md +2 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/package.json +33 -0
- package/src/index.ts +60 -0
- package/tsconfig.json +14 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 misuken
|
|
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,153 @@
|
|
|
1
|
+
# smart-result
|
|
2
|
+
|
|
3
|
+
This type library is a very smart result type available in TypeScript 4.6 or later.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
import type { Reulst } from "smart-result";
|
|
7
|
+
|
|
8
|
+
async function loadData(): Promise<Result<Data, Error>> {
|
|
9
|
+
try {
|
|
10
|
+
const response = await client.get();
|
|
11
|
+
return { ok: response.data };
|
|
12
|
+
} catch (error) {
|
|
13
|
+
if (error instanceof Error) {
|
|
14
|
+
return { error: error };
|
|
15
|
+
}
|
|
16
|
+
return { error: new Error("unknown error") };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async function example() {
|
|
22
|
+
const { ok: data, error } = await loadData();
|
|
23
|
+
if (data) {
|
|
24
|
+
console.log(data); // data: Data; error: undefined;
|
|
25
|
+
} else {
|
|
26
|
+
console.error(error); // data: undefined; error: Error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Highlight
|
|
32
|
+
|
|
33
|
+
π Good coding quality
|
|
34
|
+
π Highly readable
|
|
35
|
+
π Fewer things to remember
|
|
36
|
+
β
Safety design
|
|
37
|
+
π‘ Type only
|
|
38
|
+
|
|
39
|
+
## Intall
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
npm install -D `smart-result`
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
or
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
yarn add -D `smart-result`
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
### Void Pattern
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
import type { Reulst } from "smart-result";
|
|
57
|
+
|
|
58
|
+
async function start(): Promise<Result<true, Error>> {
|
|
59
|
+
try {
|
|
60
|
+
await client.start();
|
|
61
|
+
return { ok: true };
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (error instanceof Error) {
|
|
64
|
+
return { error: error };
|
|
65
|
+
}
|
|
66
|
+
return { error: new Error("unknown error") };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function example() {
|
|
71
|
+
// Use "ok" if you only want to know if you succeeded or not
|
|
72
|
+
const { ok, error } = await start();
|
|
73
|
+
if (ok) {
|
|
74
|
+
console.log(ok); // ok: true;
|
|
75
|
+
} else {
|
|
76
|
+
console.error(error); // ok: undefined; error: Error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Return Data Pattern
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
import type { Reulst } from "smart-result";
|
|
85
|
+
|
|
86
|
+
async function loadData(): Promise<Result<Data, Error>> {
|
|
87
|
+
try {
|
|
88
|
+
const response = await client.get();
|
|
89
|
+
return { ok: response.data };
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (error instanceof Error) {
|
|
92
|
+
return { error: error };
|
|
93
|
+
}
|
|
94
|
+
return { error: new Error("unknown error") };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function example() {
|
|
99
|
+
// Assign a name to "ok" if you want to handle the resulting information
|
|
100
|
+
const { ok: data, error } = await loadData();
|
|
101
|
+
if (data) {
|
|
102
|
+
console.log(data); // data: Data; error: undefined;
|
|
103
|
+
} else {
|
|
104
|
+
console.error(error); // data: undefined; error: Error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Return Value Pattern
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
import type { Reulst } from "smart-result";
|
|
113
|
+
|
|
114
|
+
async function loadValue(): Promise<Result<{ value: number }, Error>> {
|
|
115
|
+
try {
|
|
116
|
+
const response = await client.get();
|
|
117
|
+
// If you want to return a primitive value, wrap it with `{ value: }`.
|
|
118
|
+
return { ok: { value: response.data } };
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error instanceof Error) {
|
|
121
|
+
return { error: error };
|
|
122
|
+
}
|
|
123
|
+
return { error: new Error("unknown error") };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function example() {
|
|
128
|
+
const { ok, error } = await loadValue();
|
|
129
|
+
if (ok) {
|
|
130
|
+
console.log(ok.value); // ok: { value: number } error: undefined;
|
|
131
|
+
} else {
|
|
132
|
+
console.error(error); // data: undefined; error: Error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API
|
|
138
|
+
|
|
139
|
+
### `Result<Data extends true | Record<string, any>, Error>`
|
|
140
|
+
|
|
141
|
+
Alias for `OkResult<Data> | ErrorResult<Error>`.
|
|
142
|
+
|
|
143
|
+
### `OkResult<Data extends true | Record<string, any>>`
|
|
144
|
+
|
|
145
|
+
An object with the key `ok` and without the key `error`.
|
|
146
|
+
|
|
147
|
+
### `ErrorResult<Error extends Record<string, any>>>`
|
|
148
|
+
|
|
149
|
+
An object with the key `error` and without the key `ok`.
|
|
150
|
+
|
|
151
|
+
## LICENSE
|
|
152
|
+
|
|
153
|
+
[@misuken-now/smart-result](https://github.com/misuken-now/smart-result)γ»MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "smart-result",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "yarn clean && tsc -p ./tsconfig.json",
|
|
7
|
+
"clean": "del-cli lib module",
|
|
8
|
+
"versionup:major": "changelog -M && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version major",
|
|
9
|
+
"versionup:minor": "changelog -m && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version minor",
|
|
10
|
+
"versionup:patch": "changelog -p && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version patch"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/misuken-now/smart-result.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "misuken-now (https://github.com/misuken-now)",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/misuken-now/smart-result/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/misuken-now/smart-result#readme",
|
|
23
|
+
"main": "./lib/index.js",
|
|
24
|
+
"typings": "./lib/index.d.ts",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"generate-changelog": "^1.8.0",
|
|
27
|
+
"del-cli": "^4.0.1",
|
|
28
|
+
"typescript": "^5.4.3"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"typescript": ">=4.6.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type of the result in case of success.
|
|
3
|
+
*
|
|
4
|
+
* If a string or number is specified directly for ok, it will be judged false if an empty string or 0 is specified, so only true or Record<string, any> can be specified.
|
|
5
|
+
*/
|
|
6
|
+
export type OkResult<Data extends true | Record<string, any>> = {
|
|
7
|
+
readonly error?: never;
|
|
8
|
+
// If the result is `{}`, set it to `Record<string, unknown>` to make type resolution work as expected when the result branches.
|
|
9
|
+
readonly ok: [keyof Data] extends [never] ? Record<string, unknown> : Data;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Type of the result in case of error.
|
|
14
|
+
*/
|
|
15
|
+
export type ErrorResult<Error extends Record<string, any>> = { readonly error: Error; readonly ok?: never };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Object type for easier handling of results.
|
|
19
|
+
*
|
|
20
|
+
* @example If you do not need to return the results.
|
|
21
|
+
* async function foo(): Promise<Result<true, Error>> {
|
|
22
|
+
* try {
|
|
23
|
+
* await bar();
|
|
24
|
+
* return { ok: true };
|
|
25
|
+
* } catch (error) {
|
|
26
|
+
* if (error instanceof Error) {
|
|
27
|
+
* return { error };
|
|
28
|
+
* }
|
|
29
|
+
* return { error: new Error("unknown error") };
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* const { ok, error } = await foo();
|
|
34
|
+
* if (ok) {
|
|
35
|
+
* console.log(ok); // ok: true; error: undefined;
|
|
36
|
+
* } else {
|
|
37
|
+
* console.error(error); // ok: undefined; error: Error;
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* @example If you do need to return the results.
|
|
41
|
+
* async function foo(): Promise<Result<Data, Error>> {
|
|
42
|
+
* try {
|
|
43
|
+
* const response = await bar();
|
|
44
|
+
* return { ok: response.data };
|
|
45
|
+
* } catch (error) {
|
|
46
|
+
* if (error instanceof Error) {
|
|
47
|
+
* return { error };
|
|
48
|
+
* }
|
|
49
|
+
* return { error: new Error("unknown error") };
|
|
50
|
+
* }
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* const { ok: data, error } = await foo();
|
|
54
|
+
* if (data) {
|
|
55
|
+
* console.log(data); // data: Data; error: undefined;
|
|
56
|
+
* } else {
|
|
57
|
+
* console.error(error); // data: undefined; error: Error;
|
|
58
|
+
* }
|
|
59
|
+
*/
|
|
60
|
+
export type Result<Data extends true | Record<string, any>, Error extends Record<string, any>> = OkResult<Data> | ErrorResult<Error>;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"outDir": "./lib",
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"skipLibCheck": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*.ts"],
|
|
13
|
+
"exclude": ["node_modules"]
|
|
14
|
+
}
|