typeshi 2.2.2 → 2.2.3
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/dist/utils/io/logging.d.ts +7 -6
- package/dist/utils/io/logging.js +21 -27
- package/dist/utils/io/reading.d.ts +2 -2
- package/dist/utils/io/reading.js +3 -3
- package/dist/utils/regex/email.js +1 -0
- package/dist/utils/regex/misc.d.ts +18 -4
- package/dist/utils/regex/misc.js +35 -8
- package/dist/utils/typeValidation.d.ts +2 -2
- package/dist/utils/typeValidation.js +1 -2
- package/dist/utils/utilityTypes.d.ts +43 -16
- package/package.json +1 -1
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { ILogObj, ILogObjMeta } from "tslog";
|
|
2
2
|
/**
|
|
3
|
-
* @param
|
|
3
|
+
* @param base `string` - e.g. name of file or class
|
|
4
|
+
* - passed into `extractFileName()` if `/\\|\//.test(filename)`
|
|
4
5
|
* @param func `Function` - to get Function.name
|
|
5
6
|
* @param funcInfo `any` `(optional)` - context or params of func (converted to string)
|
|
6
7
|
* @param startLine `number` `(optional)`
|
|
7
8
|
* @param endLine `number` `(optional)`
|
|
8
9
|
* @returns **`sourceString`** `string` to use in log statements or argumentValidation calls
|
|
9
10
|
*/
|
|
10
|
-
export declare function getSourceString(
|
|
11
|
+
export declare function getSourceString(base: string, func: string | Function, funcInfo?: any, startLine?: number, endLine?: number): string;
|
|
11
12
|
/**
|
|
12
13
|
* @deprecated
|
|
13
14
|
* Auto-formats debug logs at the end of application execution.
|
|
14
15
|
* Call this function when your main application is finishing.
|
|
15
|
-
* @param
|
|
16
|
+
* @param filepaths `string[]` - optional, specific file paths to format.
|
|
16
17
|
* If not provided, will format all .txt files in the log directory.
|
|
17
18
|
* @returns `void`
|
|
18
19
|
*/
|
|
19
|
-
export declare function autoFormatLogsOnExit(
|
|
20
|
+
export declare function autoFormatLogsOnExit(filepaths?: string[]): void;
|
|
20
21
|
/**
|
|
21
22
|
* @deprecated
|
|
22
23
|
* Formats a debug log file from JSON format to a more readable text format.
|
|
@@ -31,11 +32,11 @@ export declare function formatDebugLogFile(inputPath: string, outputPath?: strin
|
|
|
31
32
|
* @deprecated
|
|
32
33
|
* Formats all debug log files in the log directory.
|
|
33
34
|
* Looks for .txt files and creates .FORMATTED.txt versions.
|
|
34
|
-
* @param
|
|
35
|
+
* @param logDir `string` - optional, path to the log directory.
|
|
35
36
|
* If not provided, uses LOCAL_LOG_DIR from setupLog.ts
|
|
36
37
|
* @returns `void`
|
|
37
38
|
*/
|
|
38
|
-
export declare function formatAllDebugLogs(
|
|
39
|
+
export declare function formatAllDebugLogs(logDir: string): void;
|
|
39
40
|
/**
|
|
40
41
|
* @deprecated
|
|
41
42
|
* reduce metadata to two entries, then return stringified `logObj`
|
package/dist/utils/io/logging.js
CHANGED
|
@@ -44,22 +44,24 @@ exports.formatLogObj = formatLogObj;
|
|
|
44
44
|
/**
|
|
45
45
|
* @file src/utils/io/logging.ts
|
|
46
46
|
*/
|
|
47
|
-
const
|
|
47
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
48
48
|
const setupLog_1 = require("../../config/setupLog");
|
|
49
49
|
const typeValidation_1 = require("../typeValidation");
|
|
50
50
|
const regex_1 = require("../regex");
|
|
51
51
|
const validate = __importStar(require("../argumentValidation"));
|
|
52
52
|
const node_path_1 = __importDefault(require("node:path"));
|
|
53
53
|
/**
|
|
54
|
-
* @param
|
|
54
|
+
* @param base `string` - e.g. name of file or class
|
|
55
|
+
* - passed into `extractFileName()` if `/\\|\//.test(filename)`
|
|
55
56
|
* @param func `Function` - to get Function.name
|
|
56
57
|
* @param funcInfo `any` `(optional)` - context or params of func (converted to string)
|
|
57
58
|
* @param startLine `number` `(optional)`
|
|
58
59
|
* @param endLine `number` `(optional)`
|
|
59
60
|
* @returns **`sourceString`** `string` to use in log statements or argumentValidation calls
|
|
60
61
|
*/
|
|
61
|
-
function getSourceString(
|
|
62
|
-
|
|
62
|
+
function getSourceString(base, func, funcInfo, startLine, endLine) {
|
|
63
|
+
if (/\\|\//.test(base))
|
|
64
|
+
base = (0, regex_1.extractFileName)(base);
|
|
63
65
|
let lineNumberText = ((0, typeValidation_1.isInteger)(startLine)
|
|
64
66
|
? `:${startLine}`
|
|
65
67
|
: '');
|
|
@@ -68,30 +70,23 @@ function getSourceString(fileName, func, funcInfo, startLine, endLine) {
|
|
|
68
70
|
? lineNumberText + `-${endLine}`
|
|
69
71
|
: '');
|
|
70
72
|
let funcName = typeof func === 'string' ? func : func.name;
|
|
71
|
-
return `[${
|
|
73
|
+
return `[${base}.${funcName}(${(0, typeValidation_1.isNonEmptyString)(funcInfo) ? ` ${funcInfo} ` : ''})${lineNumberText}]`;
|
|
72
74
|
}
|
|
73
75
|
/**
|
|
74
76
|
* @deprecated
|
|
75
77
|
* Auto-formats debug logs at the end of application execution.
|
|
76
78
|
* Call this function when your main application is finishing.
|
|
77
|
-
* @param
|
|
79
|
+
* @param filepaths `string[]` - optional, specific file paths to format.
|
|
78
80
|
* If not provided, will format all .txt files in the log directory.
|
|
79
81
|
* @returns `void`
|
|
80
82
|
*/
|
|
81
|
-
function autoFormatLogsOnExit(
|
|
82
|
-
const source = getSourceString(__filename, autoFormatLogsOnExit.name, `Array<string>(${(
|
|
83
|
-
if (!(0, typeValidation_1.isStringArray)(filePaths)) {
|
|
84
|
-
setupLog_1.typeshiLogger.warn([`${source} Invalid param 'filePaths'`,
|
|
85
|
-
`Expected: string[] (array of filePaths)`,
|
|
86
|
-
`Received: ${typeof filePaths} = '${JSON.stringify(filePaths)}'`
|
|
87
|
-
].join(setupLog_1.INDENT_LOG_LINE));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
83
|
+
function autoFormatLogsOnExit(filepaths) {
|
|
84
|
+
const source = getSourceString(__filename, autoFormatLogsOnExit.name, `Array<string>(${(filepaths ?? []).length})`);
|
|
90
85
|
try {
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
validate.arrayArgument(source, { filepaths, isStringArray: typeValidation_1.isStringArray });
|
|
87
|
+
for (const filePath of filepaths ?? []) {
|
|
88
|
+
if (node_fs_1.default.existsSync(filePath))
|
|
93
89
|
formatDebugLogFile(filePath);
|
|
94
|
-
}
|
|
95
90
|
}
|
|
96
91
|
}
|
|
97
92
|
catch (error) {
|
|
@@ -116,10 +111,10 @@ function formatDebugLogFile(inputPath, outputPath) {
|
|
|
116
111
|
const parsedPath = node_path_1.default.parse(inputPath);
|
|
117
112
|
outputPath = node_path_1.default.join(parsedPath.dir, `${parsedPath.name}.FORMATTED${parsedPath.ext}`);
|
|
118
113
|
}
|
|
119
|
-
const fileContent =
|
|
114
|
+
const fileContent = node_fs_1.default.readFileSync(inputPath, 'utf-8');
|
|
120
115
|
const formattedContent = formatLogContent(fileContent);
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
node_fs_1.default.writeFileSync(outputPath, formattedContent, { encoding: 'utf-8' });
|
|
117
|
+
setupLog_1.typeshiHiddenLogger.info(`[formatDebugLogFile()] Formatted log file saved to '${outputPath}'`);
|
|
123
118
|
}
|
|
124
119
|
catch (error) {
|
|
125
120
|
setupLog_1.typeshiLogger.error(`${source} Error formatting log file:'`, error);
|
|
@@ -216,18 +211,17 @@ function formatSingleLogEntry(logObj) {
|
|
|
216
211
|
* @deprecated
|
|
217
212
|
* Formats all debug log files in the log directory.
|
|
218
213
|
* Looks for .txt files and creates .FORMATTED.txt versions.
|
|
219
|
-
* @param
|
|
214
|
+
* @param logDir `string` - optional, path to the log directory.
|
|
220
215
|
* If not provided, uses LOCAL_LOG_DIR from setupLog.ts
|
|
221
216
|
* @returns `void`
|
|
222
217
|
*/
|
|
223
|
-
function formatAllDebugLogs(
|
|
224
|
-
|
|
225
|
-
if (!fs.existsSync(logDir)) {
|
|
218
|
+
function formatAllDebugLogs(logDir) {
|
|
219
|
+
if (!node_fs_1.default.existsSync(logDir)) {
|
|
226
220
|
setupLog_1.typeshiLogger.warn(`[formatAllDebugLogs()] Log directory does not exist: ${logDir}`);
|
|
227
221
|
return;
|
|
228
222
|
}
|
|
229
223
|
try {
|
|
230
|
-
const files =
|
|
224
|
+
const files = node_fs_1.default.readdirSync(logDir);
|
|
231
225
|
const txtFiles = files.filter(file => file.endsWith('.txt') && !file.includes('.FORMATTED.'));
|
|
232
226
|
if (txtFiles.length === 0) {
|
|
233
227
|
setupLog_1.typeshiLogger.warn(`[formatAllDebugLogs()] No .txt log files found in ${logDir}`);
|
|
@@ -237,7 +231,7 @@ function formatAllDebugLogs(logDirectory) {
|
|
|
237
231
|
const inputPath = node_path_1.default.join(logDir, txtFile);
|
|
238
232
|
try {
|
|
239
233
|
formatDebugLogFile(inputPath);
|
|
240
|
-
|
|
234
|
+
setupLog_1.typeshiHiddenLogger.info(`[formatAllDebugLogs()] Formatted: ${txtFile}`);
|
|
241
235
|
}
|
|
242
236
|
catch (error) {
|
|
243
237
|
setupLog_1.typeshiLogger.error(`[formatAllDebugLogs()] Failed to format ${txtFile}:`, error);
|
|
@@ -2,9 +2,9 @@ import { StringCleanOptions } from "../regex";
|
|
|
2
2
|
import { DirectoryFileOptions, FileData, FileExtension } from "./types/Io";
|
|
3
3
|
import { DelimiterCharacterEnum } from "./types";
|
|
4
4
|
/** checks if `pathString (value)` points to an existing directory */
|
|
5
|
-
export declare function isDirectory(value: any):
|
|
5
|
+
export declare function isDirectory(value: any): boolean;
|
|
6
6
|
/** checks if `pathString (value)` points to an existing file */
|
|
7
|
-
export declare function isFile(value: string):
|
|
7
|
+
export declare function isFile(value: string): boolean;
|
|
8
8
|
/**
|
|
9
9
|
* Determines the proper delimiter based on file type or extension
|
|
10
10
|
* @param filePath `string` Path to the file
|
package/dist/utils/io/reading.js
CHANGED
|
@@ -472,8 +472,8 @@ async function getOneToOneDictionary(arg1, keyColumn, valueColumn, keyOptions, v
|
|
|
472
472
|
*/
|
|
473
473
|
async function getColumnValues(arg1, columnName, cleaner, allowDuplicates = false) {
|
|
474
474
|
const source = (0, logging_1.getSourceString)(__filename, getColumnValues.name);
|
|
475
|
-
validate.stringArgument(source, {
|
|
476
|
-
validate.booleanArgument(source, {
|
|
475
|
+
// validate.stringArgument(source, {columnName});
|
|
476
|
+
// validate.booleanArgument(source, {allowDuplicates});
|
|
477
477
|
if (cleaner)
|
|
478
478
|
validate.functionArgument(source, { cleaner });
|
|
479
479
|
let rows = await handleFileArgument(arg1, getColumnValues.name, [columnName]);
|
|
@@ -497,7 +497,7 @@ async function getColumnValues(arg1, columnName, cleaner, allowDuplicates = fals
|
|
|
497
497
|
*/
|
|
498
498
|
async function getIndexedColumnValues(arg1, columnName, cleaner) {
|
|
499
499
|
const source = `[reading.getIndexedColumnValues()]`;
|
|
500
|
-
validate.stringArgument(source, {
|
|
500
|
+
// validate.stringArgument(source, {columnName});
|
|
501
501
|
if (cleaner)
|
|
502
502
|
validate.functionArgument(source, { cleaner });
|
|
503
503
|
let rows = await handleFileArgument(arg1, getIndexedColumnValues.name, [columnName]);
|
|
@@ -8,6 +8,7 @@ exports.extractEmail = extractEmail;
|
|
|
8
8
|
* @file src/utils/regex/email.ts
|
|
9
9
|
*/
|
|
10
10
|
const Str_1 = require("./Str");
|
|
11
|
+
// @TODO parameterize replacements in parsed displayName
|
|
11
12
|
/**
|
|
12
13
|
* @param s `string`
|
|
13
14
|
* - e.g. `"{local}@{domain}"`, `"{displayName} <{local}@{domain}>"`
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* `extractFileNameFromPath`
|
|
6
6
|
* essentially a wrapper for path.basename() for short-hand convenience
|
|
7
|
-
* @param
|
|
7
|
+
* @param filepath `string` e.g. pass in the node module variable `__filename`
|
|
8
8
|
* @param removeExtension `boolean` `optional, default = true` - flag indicating
|
|
9
|
-
* whether or not to remove the file extension from the
|
|
10
|
-
* @returns **`
|
|
9
|
+
* whether or not to remove the file extension from the filename
|
|
10
|
+
* @returns **`filename`** `string`
|
|
11
11
|
*/
|
|
12
|
-
export declare function extractFileName(
|
|
12
|
+
export declare function extractFileName(filepath: string, removeExtension?: boolean): string;
|
|
13
13
|
/**
|
|
14
14
|
* = `= /^[^/\\:*?"<>|]+(\.[^/\\:*?"<>|]+)$/`
|
|
15
15
|
*/
|
|
@@ -33,3 +33,17 @@ export declare const KOREA_ADDRESS_LATIN_TEXT_PATTERN: RegExp;
|
|
|
33
33
|
* @returns **`leaf`**: `string` - the extracted `leaf` or the original value if no extraction performed
|
|
34
34
|
*/
|
|
35
35
|
export declare function extractLeaf(value: string, classDelimiter: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* @param keepParentheses `boolean (optional)` `default = false`
|
|
38
|
+
* @returns **new RegExp** with same flags as `re`
|
|
39
|
+
* - returns `re` if does not have `groupName`
|
|
40
|
+
* @example
|
|
41
|
+
* const re = /(?<name>)\s*abcdefg/;
|
|
42
|
+
* let groupName = 'name';
|
|
43
|
+
* let value = 'Bob';
|
|
44
|
+
* let result1 = replaceGroupWithLiteral(re, groupName, value, false);
|
|
45
|
+
* // result1.source === 'Bob\\s*abcdefg'
|
|
46
|
+
* let result2 = replaceGroupWithLiteral(re, groupName, value, true);
|
|
47
|
+
* // result2.source === '(Bob)\\s*abcdefg'
|
|
48
|
+
*/
|
|
49
|
+
export declare function replaceGroupWithLiteral(re: RegExp, groupName: string, value: string, keepParentheses?: boolean): RegExp;
|
package/dist/utils/regex/misc.js
CHANGED
|
@@ -9,25 +9,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.KOREA_ADDRESS_LATIN_TEXT_PATTERN = exports.DATE_STRING_PATTERN = exports.FILE_NAME_WITH_EXTENSION_PATTERN = void 0;
|
|
10
10
|
exports.extractFileName = extractFileName;
|
|
11
11
|
exports.extractLeaf = extractLeaf;
|
|
12
|
+
exports.replaceGroupWithLiteral = replaceGroupWithLiteral;
|
|
12
13
|
const typeValidation_1 = require("../typeValidation");
|
|
13
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
15
|
/**
|
|
15
16
|
* `extractFileNameFromPath`
|
|
16
17
|
* essentially a wrapper for path.basename() for short-hand convenience
|
|
17
|
-
* @param
|
|
18
|
+
* @param filepath `string` e.g. pass in the node module variable `__filename`
|
|
18
19
|
* @param removeExtension `boolean` `optional, default = true` - flag indicating
|
|
19
|
-
* whether or not to remove the file extension from the
|
|
20
|
-
* @returns **`
|
|
20
|
+
* whether or not to remove the file extension from the filename
|
|
21
|
+
* @returns **`filename`** `string`
|
|
21
22
|
*/
|
|
22
|
-
function extractFileName(
|
|
23
|
-
if (!(0, typeValidation_1.isNonEmptyString)(
|
|
23
|
+
function extractFileName(filepath, removeExtension = true) {
|
|
24
|
+
if (!(0, typeValidation_1.isNonEmptyString)(filepath)) {
|
|
24
25
|
return 'undefined';
|
|
25
26
|
}
|
|
26
|
-
let
|
|
27
|
+
let filename = node_path_1.default.basename(filepath);
|
|
27
28
|
if (removeExtension) {
|
|
28
|
-
|
|
29
|
+
filename = filename.replace(/(?<=.+)\.[a-z0-9]{1,}$/i, '');
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return filename;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* = `= /^[^/\\:*?"<>|]+(\.[^/\\:*?"<>|]+)$/`
|
|
@@ -59,3 +60,29 @@ function extractLeaf(value, classDelimiter) {
|
|
|
59
60
|
}
|
|
60
61
|
return result || value;
|
|
61
62
|
}
|
|
63
|
+
// @consideration rename keepParentheses to keepGroup or keepGrouping or keepGroupParentheses ?
|
|
64
|
+
/**
|
|
65
|
+
* @param keepParentheses `boolean (optional)` `default = false`
|
|
66
|
+
* @returns **new RegExp** with same flags as `re`
|
|
67
|
+
* - returns `re` if does not have `groupName`
|
|
68
|
+
* @example
|
|
69
|
+
* const re = /(?<name>)\s*abcdefg/;
|
|
70
|
+
* let groupName = 'name';
|
|
71
|
+
* let value = 'Bob';
|
|
72
|
+
* let result1 = replaceGroupWithLiteral(re, groupName, value, false);
|
|
73
|
+
* // result1.source === 'Bob\\s*abcdefg'
|
|
74
|
+
* let result2 = replaceGroupWithLiteral(re, groupName, value, true);
|
|
75
|
+
* // result2.source === '(Bob)\\s*abcdefg'
|
|
76
|
+
*/
|
|
77
|
+
function replaceGroupWithLiteral(re, groupName, value, keepParentheses = false) {
|
|
78
|
+
let pat = (keepParentheses
|
|
79
|
+
? `(?<=\\\()` + `\\\?<${groupName}>` + `(?=\\\))`
|
|
80
|
+
: `\\\(` + `\\\?<${groupName}>` + `\\\)`);
|
|
81
|
+
let groupPattern = new RegExp(pat);
|
|
82
|
+
if (!groupPattern.test(re.source)) { // re does not contain group
|
|
83
|
+
console.warn(`[regex.misc.replaceGroupWithLiteral()] re does not contain group '${groupName}'`);
|
|
84
|
+
return re;
|
|
85
|
+
}
|
|
86
|
+
let newSource = re.source.replace(groupPattern, value);
|
|
87
|
+
return new RegExp(newSource, re.flags);
|
|
88
|
+
}
|
|
@@ -81,7 +81,7 @@ export declare function isInteger(value: unknown, requireNonNegative?: boolean):
|
|
|
81
81
|
* - `if` `false` then `value` is allowed to be an array
|
|
82
82
|
* @returns **`isObject`** `boolean` `value is T`
|
|
83
83
|
*/
|
|
84
|
-
export declare function isObject<T extends object = Record<
|
|
84
|
+
export declare function isObject<T extends object = Record<keyof any, any>>(value: unknown, requireNonEmpty?: boolean, requireNonArray?: boolean): value is T;
|
|
85
85
|
export declare function isPositveInteger(value: unknown): value is number;
|
|
86
86
|
export declare const isType: <T>(value: any, guard: (v: any, ...args: any[]) => v is T, ...args: any[]) => value is T;
|
|
87
87
|
/**
|
|
@@ -235,4 +235,4 @@ export declare function hasNonTrivialEntries<T extends object>(obj: T, requireAl
|
|
|
235
235
|
* - **`true`** `if` `obj` is of type 'object' and has the required key(s),
|
|
236
236
|
* - **`false`** `otherwise`
|
|
237
237
|
*/
|
|
238
|
-
export declare function hasKeys<T extends object>(obj: T, keys: Array<keyof T> | string[] | string, requireAll?: boolean, restrictKeys?: boolean): boolean;
|
|
238
|
+
export declare function hasKeys<T extends object = any>(obj: T, keys: Array<keyof T> | string[] | string, requireAll?: boolean, restrictKeys?: boolean): boolean;
|
|
@@ -110,7 +110,7 @@ function isNumeric(value, requireInteger = false, requireNonNegative = false) {
|
|
|
110
110
|
function isNonEmptyString(value, requireNonSpace = false) {
|
|
111
111
|
return (typeof value === 'string'
|
|
112
112
|
&& (requireNonSpace
|
|
113
|
-
? value.trim() !== ''
|
|
113
|
+
? value.trim() !== '' // Boolean(value.trim())
|
|
114
114
|
: value.length > 0));
|
|
115
115
|
}
|
|
116
116
|
function isPrimitiveValue(value) {
|
|
@@ -376,7 +376,6 @@ function hasNonTrivialEntries(obj, requireAll = false) {
|
|
|
376
376
|
? Object.values(obj).every(v => !isEmpty(v))
|
|
377
377
|
: Object.values(obj).some(v => !isEmpty(v)));
|
|
378
378
|
}
|
|
379
|
-
// @TODO add overload on param `keys` where keys = `{ required: string[], optional: string[] }`
|
|
380
379
|
/**
|
|
381
380
|
* @deprecated
|
|
382
381
|
* @note uses `key in obj` for each element of param `keys`
|
|
@@ -1,39 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file src/utils/utilityTypes.ts
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* @template Required - Whether the key is required
|
|
6
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
7
|
+
* - `default = false`
|
|
8
|
+
*/
|
|
9
|
+
export type NumberKeys<T, Required extends boolean = false> = Exclude<{
|
|
5
10
|
[K in keyof T]: Required extends true ? (T[K] extends number ? K : never) : (T[K] extends number | undefined ? K : never);
|
|
6
|
-
}[keyof T][];
|
|
7
|
-
|
|
11
|
+
}[keyof T], undefined>[];
|
|
12
|
+
/**
|
|
13
|
+
* @template Required - Whether the key is required
|
|
14
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
15
|
+
* - `default = false`
|
|
16
|
+
*/
|
|
17
|
+
export type ArrayKeys<T, Required extends boolean = false> = Exclude<{
|
|
8
18
|
[K in keyof T]: Required extends true ? (T[K] extends Array<any> ? K : never) : (T[K] extends Array<any> | undefined ? K : never);
|
|
9
|
-
}[keyof T][];
|
|
10
|
-
|
|
19
|
+
}[keyof T], undefined>[];
|
|
20
|
+
/**
|
|
21
|
+
* @template Required - Whether the key is required
|
|
22
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
23
|
+
* - `default = false`
|
|
24
|
+
*/
|
|
25
|
+
export type ArrayOfTypeKeys<T, U, Required extends boolean = false> = Exclude<{
|
|
11
26
|
[K in keyof T]: Required extends true ? (T[K] extends Array<U> ? K : never) : (T[K] extends Array<U> | undefined ? K : never);
|
|
12
|
-
}[keyof T][];
|
|
13
|
-
|
|
27
|
+
}[keyof T], undefined>[];
|
|
28
|
+
/**
|
|
29
|
+
* @template Required - Whether the key is required
|
|
30
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
31
|
+
* - `default = false`
|
|
32
|
+
*/
|
|
33
|
+
export type StringKeys<T, Required extends boolean = false> = Exclude<{
|
|
14
34
|
[K in keyof T]: Required extends true ? (T[K] extends string ? K : never) : (T[K] extends string | undefined ? K : never);
|
|
15
|
-
}[keyof T][];
|
|
16
|
-
|
|
35
|
+
}[keyof T], undefined>[];
|
|
36
|
+
/**
|
|
37
|
+
* @template Required - Whether the key is required
|
|
38
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
39
|
+
* - `default = false`
|
|
40
|
+
*/
|
|
41
|
+
export type PrimitiveKeys<T, Required extends boolean = false> = Exclude<{
|
|
17
42
|
[K in keyof T]: Required extends true ? (T[K] extends string | number | boolean | null ? K : never) : (T[K] extends string | number | boolean | null | undefined ? K : never);
|
|
18
|
-
}[keyof T][];
|
|
43
|
+
}[keyof T], undefined>[];
|
|
19
44
|
export type Primitive = string | number | boolean | null | undefined;
|
|
20
45
|
/** Get the union of all values of `T` (like `valueof T`) */
|
|
21
|
-
export type ValueOf<T> = T[keyof T];
|
|
46
|
+
export type ValueOf<T> = T extends object ? T[keyof T] : T;
|
|
22
47
|
/**
|
|
23
48
|
* Keys of `T` whose values extend a given type `U`
|
|
24
49
|
* @template T - The object type
|
|
25
50
|
* @template U - The type to check each `T[K]` against
|
|
26
|
-
* @template Required - Whether the key is required
|
|
27
|
-
|
|
28
|
-
|
|
51
|
+
* @template Required - Whether the key is required
|
|
52
|
+
* (allows for `K` where `T[K]` can be `undefined` if `false`)
|
|
53
|
+
* - `default = false`
|
|
54
|
+
* */
|
|
55
|
+
export type KeysOfType<T, U, Required extends boolean = false> = Exclude<{
|
|
29
56
|
[K in keyof T]: Required extends true ? (T[K] extends U ? K : never) : (T[K] extends U | undefined ? K : never);
|
|
30
|
-
}[keyof T][];
|
|
57
|
+
}[keyof T], undefined>[];
|
|
31
58
|
/**
|
|
32
59
|
* use for non-strict autocomplete of enum/literal value types
|
|
33
60
|
* @example
|
|
34
61
|
* JobPlatformEnum = { GREENHOUSE: 'GREENHOUSE', WORKDAY: 'WORKDAY' } as const;
|
|
35
62
|
* type JobPlatformEnum = (typeof JobPlatformEnum)[keyof typeof JobPlatformEnum]; // 'GREENHOUSE' | 'WORKDAY'
|
|
36
|
-
* let key: NonStrict<JobPlatformEnum>; //
|
|
63
|
+
* let key: NonStrict<JobPlatformEnum>; // allows any string, but will have the enum values as suggested auto-complete values
|
|
37
64
|
* key = 'hello'; // ok
|
|
38
65
|
* key = 9; // Error: Type '9' is not assignable to type 'NonStrict<JobPlatformEnum>'
|
|
39
66
|
* */
|