Comparing version 1.0.0 to 1.0.1
@@ -1,7 +0,8 @@ | ||
import { IfAnyOrUnknown } from './utils'; | ||
export type ArrayItem<T> = T extends readonly (infer U)[] ? U : unknown; | ||
export type U2a<U, R> = [ | ||
R | ||
] extends [never] ? IfAnyOrUnknown<U, unknown, U extends readonly unknown[] ? U : unknown[]> : IfAnyOrUnknown<R, unknown>[]; | ||
import { IfAnyOrUnknown, IfNever } from './utils'; | ||
/** | ||
* Convert any type to array. | ||
* Try to extract all explicit array types from `U`, if `never` fallback to an `unknown[]`. | ||
*/ | ||
export type ToArray<U> = IfAnyOrUnknown<U, unknown[], IfNever<Extract<U, readonly unknown[]>, never[]>>; | ||
/** | ||
* Converts unknown to an array. | ||
@@ -11,2 +12,2 @@ * If `callbackfn` is provided, each item will be mapped using it. | ||
*/ | ||
export declare function u2a<U, R = never>(u: U, callbackfn?: (item: ArrayItem<U>) => R): U2a<U, R>; | ||
export declare function u2a<U, R = never>(u: U, callbackfn?: (item: ToArray<U>[number]) => R): IfNever<R, IfAnyOrUnknown<U, unknown[], IfNever<Extract<U, readonly unknown[]>, never[], Extract<U, readonly unknown[]>>>, IfAnyOrUnknown<R, unknown>[]>; |
@@ -11,8 +11,8 @@ "use strict"; | ||
var a = u instanceof Array ? u : []; | ||
if (!callbackfn) | ||
return a; | ||
// Do not use `a.map(...)`, because `a.map` may be dirty. | ||
return Array.prototype.map.call(a, function (v) { return callbackfn(v); }); | ||
return (callbackfn | ||
? // Do not use `a.map(...)`, because `a.map` may be dirty. | ||
Array.prototype.map.call(a, function (v) { return callbackfn(v); }) | ||
: a); | ||
} | ||
exports.u2a = u2a; | ||
//# sourceMappingURL=u2a.js.map |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a boolean, and if `u` is not a boolean, calls the conversion function or returns an undefined. | ||
* Convert `what` to a boolean, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a boolean, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2b<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, boolean | R, U extends boolean ? U : R>; | ||
export declare function u2b<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, boolean | R, U extends boolean ? U : R>; |
@@ -11,8 +11,12 @@ "use strict"; | ||
/** | ||
* Converts `u` to a boolean, and if `u` is not a boolean, calls the conversion function or returns an undefined. | ||
* Convert `what` to a boolean, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a boolean, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
function u2b(u, converter) { | ||
return (0, utils_1.u2x)('boolean', u, converter); | ||
function u2b(what, defaultValueOrConverter) { | ||
return (0, utils_1.u2x)('boolean', what, defaultValueOrConverter); | ||
} | ||
exports.u2b = u2b; | ||
//# sourceMappingURL=u2b.js.map |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a number, and if `u` is not a number, calls the conversion function or returns an undefined. | ||
* Convert `what` to a number, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a number, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2n<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, number | R, U extends number ? U : R>; | ||
export declare function u2n<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, number | R, U extends number ? U : R>; |
@@ -11,8 +11,12 @@ "use strict"; | ||
/** | ||
* Converts `u` to a number, and if `u` is not a number, calls the conversion function or returns an undefined. | ||
* Convert `what` to a number, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a number, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
function u2n(u, converter) { | ||
return (0, utils_1.u2x)('number', u, converter); | ||
function u2n(what, defaultValueOrConverter) { | ||
return (0, utils_1.u2x)('number', what, defaultValueOrConverter); | ||
} | ||
exports.u2n = u2n; | ||
//# sourceMappingURL=u2n.js.map |
import { IfAnyOrUnknown, DirtyObject } from './utils'; | ||
/** | ||
* Convert any type to object by folloing steps: | ||
* | ||
* - If `U` is a `string`, returns a `String` object. | ||
* - If `U` is a `number`, returns a `Number` object. | ||
* - If `U` is a `boolean`, returns a `Boolean` object. | ||
* - If `U` is an `object`, * returns `U` itself. | ||
* - Otherwise returns an `unknown`. | ||
*/ | ||
export type ToObject<U> = U extends object ? U : U extends string ? String : U extends number ? Number : U extends boolean ? Boolean : unknown; | ||
export type U2o<U> = IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; | ||
/** | ||
@@ -12,2 +20,2 @@ * Convert unknown to object. | ||
*/ | ||
export declare function u2o<U>(u: U): U2o<U>; | ||
export declare function u2o<U>(u: U): IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a string, and if `u` is not a string, calls the conversion function or returns an undefined. | ||
* Convert `what` to a string, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a string, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2s<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, string | R, U extends string ? U : R>; | ||
export declare function u2s<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, string | R, U extends string ? U : R>; |
@@ -11,8 +11,12 @@ "use strict"; | ||
/** | ||
* Converts `u` to a string, and if `u` is not a string, calls the conversion function or returns an undefined. | ||
* Convert `what` to a string, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a string, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
function u2s(u, converter) { | ||
return (0, utils_1.u2x)('string', u, converter); | ||
function u2s(what, defaultValueOrConverter) { | ||
return (0, utils_1.u2x)('string', what, defaultValueOrConverter); | ||
} | ||
exports.u2s = u2s; | ||
//# sourceMappingURL=u2s.js.map |
@@ -1,17 +0,13 @@ | ||
export type IfAnyOrUnknown<T, Y, N = T> = unknown extends T ? Y : N; | ||
/** | ||
* For each type of a union `U`, if it is extended from `E`, it is kept, otherwise it is converted to `R`, | ||
* and finally each mapped type is merged into a new union. | ||
* | ||
* For example: | ||
* | ||
* - `U2x<number, 1 | 2, null>` results `1 | 2` | ||
* - `U2x<number, 'a', null>` results `null` | ||
* - `U2x<number, 1 | 2 | 'a', null>` results `1 | 2 | null` | ||
* - `U2x<number, unknown, null>` results `number | null` | ||
* | ||
* NOTE: If `U` is `any` or `unknown`, return the `P | R` directly. | ||
* If `U` is `any` or `unknown`, returns `Y` else returns `N`. | ||
*/ | ||
export type U2x<E, U, R = unknown> = IfAnyOrUnknown<U, E | R, U extends E ? U : R>; | ||
type TypeMap = { | ||
export type IfAnyOrUnknown<U, Y, N = U> = unknown extends U ? Y : N; | ||
/** | ||
* If `U` is `never`, returns `Y` else returns `N`. | ||
*/ | ||
export type IfNever<U, Y, N = U> = [U] extends [never] ? Y : N; | ||
/** | ||
* Maps a JavaScript typeof string to a real TypeScript type. | ||
*/ | ||
export type JTypes = { | ||
string: string; | ||
@@ -22,6 +18,17 @@ number: number; | ||
/** | ||
* Converts `u` to a the `t` type, calls the conversion function or returns an undefined. | ||
* A dirty object, any propertis can be access and got an unknow value. | ||
*/ | ||
export declare function u2x<T extends keyof TypeMap, U, R = undefined>(t: T, u: U, converter?: (u: U) => R): IfAnyOrUnknown<U, R | TypeMap[T], U extends TypeMap[T] ? U : R>; | ||
export type DirtyObject = Record<PropertyKey, unknown>; | ||
export {}; | ||
/** | ||
* A conversion function that converts `value` to any you want. | ||
*/ | ||
export type Converter<V, R> = (value: V) => R; | ||
/** | ||
* If `what` matching `type`, return `what` directly, otherwise try to call a conversion function and return. | ||
* If the conversion function is also not provided, the default value (may be undefined) will be returned. | ||
* | ||
* @param type Expected type. | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2x<T extends keyof JTypes, U, R = undefined>(type: T, what: U, defaultValueOrConverter?: R | ((u: U) => R)): IfAnyOrUnknown<U, R | JTypes[T], U extends JTypes[T] ? U : R>; |
@@ -5,8 +5,27 @@ "use strict"; | ||
/** | ||
* Converts `u` to a the `t` type, calls the conversion function or returns an undefined. | ||
* Convert something, whether it is a value or already a conversion function, to a converter. | ||
* | ||
* NOTE: In fact, even if value type is a 'function', we still cannot assert that it is a `Converter`, | ||
* as it may also be a `() => void` that cannot receiving any parameters. | ||
* Anyway, we force it to be treated as a `Convert`, if it is a function. | ||
* TypeScript does not support type exclusion, otherwise defining `R` as `Exclude<any, Function>` would be better. | ||
* | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
* @returns A converter function. | ||
*/ | ||
function u2x(t, u, converter) { | ||
return (typeof u === t ? u : converter === null || converter === void 0 ? void 0 : converter(u)); | ||
var toConverter = function (defaultValueOrConverter) { | ||
return (typeof defaultValueOrConverter === 'function' ? defaultValueOrConverter : function () { return defaultValueOrConverter; }); | ||
}; | ||
/** | ||
* If `what` matching `type`, return `what` directly, otherwise try to call a conversion function and return. | ||
* If the conversion function is also not provided, the default value (may be undefined) will be returned. | ||
* | ||
* @param type Expected type. | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
function u2x(type, what, defaultValueOrConverter) { | ||
return (typeof what === type ? what : toConverter(defaultValueOrConverter)(what)); | ||
} | ||
exports.u2x = u2x; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,7 +0,8 @@ | ||
import { IfAnyOrUnknown } from './utils'; | ||
export type ArrayItem<T> = T extends readonly (infer U)[] ? U : unknown; | ||
export type U2a<U, R> = [ | ||
R | ||
] extends [never] ? IfAnyOrUnknown<U, unknown, U extends readonly unknown[] ? U : unknown[]> : IfAnyOrUnknown<R, unknown>[]; | ||
import { IfAnyOrUnknown, IfNever } from './utils'; | ||
/** | ||
* Convert any type to array. | ||
* Try to extract all explicit array types from `U`, if `never` fallback to an `unknown[]`. | ||
*/ | ||
export type ToArray<U> = IfAnyOrUnknown<U, unknown[], IfNever<Extract<U, readonly unknown[]>, never[]>>; | ||
/** | ||
* Converts unknown to an array. | ||
@@ -11,2 +12,2 @@ * If `callbackfn` is provided, each item will be mapped using it. | ||
*/ | ||
export declare function u2a<U, R = never>(u: U, callbackfn?: (item: ArrayItem<U>) => R): U2a<U, R>; | ||
export declare function u2a<U, R = never>(u: U, callbackfn?: (item: ToArray<U>[number]) => R): IfNever<R, IfAnyOrUnknown<U, unknown[], IfNever<Extract<U, readonly unknown[]>, never[], Extract<U, readonly unknown[]>>>, IfAnyOrUnknown<R, unknown>[]>; |
@@ -8,7 +8,7 @@ /** | ||
var a = u instanceof Array ? u : []; | ||
if (!callbackfn) | ||
return a; | ||
// Do not use `a.map(...)`, because `a.map` may be dirty. | ||
return Array.prototype.map.call(a, function (v) { return callbackfn(v); }); | ||
return (callbackfn | ||
? // Do not use `a.map(...)`, because `a.map` may be dirty. | ||
Array.prototype.map.call(a, function (v) { return callbackfn(v); }) | ||
: a); | ||
} | ||
//# sourceMappingURL=u2a.js.map |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a boolean, and if `u` is not a boolean, calls the conversion function or returns an undefined. | ||
* Convert `what` to a boolean, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a boolean, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2b<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, boolean | R, U extends boolean ? U : R>; | ||
export declare function u2b<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, boolean | R, U extends boolean ? U : R>; |
@@ -8,7 +8,11 @@ import { u2x } from './utils'; | ||
/** | ||
* Converts `u` to a boolean, and if `u` is not a boolean, calls the conversion function or returns an undefined. | ||
* Convert `what` to a boolean, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a boolean, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2b(u, converter) { | ||
return u2x('boolean', u, converter); | ||
export function u2b(what, defaultValueOrConverter) { | ||
return u2x('boolean', what, defaultValueOrConverter); | ||
} | ||
//# sourceMappingURL=u2b.js.map |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a number, and if `u` is not a number, calls the conversion function or returns an undefined. | ||
* Convert `what` to a number, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a number, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2n<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, number | R, U extends number ? U : R>; | ||
export declare function u2n<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, number | R, U extends number ? U : R>; |
@@ -8,7 +8,11 @@ import { u2x } from './utils'; | ||
/** | ||
* Converts `u` to a number, and if `u` is not a number, calls the conversion function or returns an undefined. | ||
* Convert `what` to a number, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a number, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2n(u, converter) { | ||
return u2x('number', u, converter); | ||
export function u2n(what, defaultValueOrConverter) { | ||
return u2x('number', what, defaultValueOrConverter); | ||
} | ||
//# sourceMappingURL=u2n.js.map |
import { IfAnyOrUnknown, DirtyObject } from './utils'; | ||
/** | ||
* Convert any type to object by folloing steps: | ||
* | ||
* - If `U` is a `string`, returns a `String` object. | ||
* - If `U` is a `number`, returns a `Number` object. | ||
* - If `U` is a `boolean`, returns a `Boolean` object. | ||
* - If `U` is an `object`, * returns `U` itself. | ||
* - Otherwise returns an `unknown`. | ||
*/ | ||
export type ToObject<U> = U extends object ? U : U extends string ? String : U extends number ? Number : U extends boolean ? Boolean : unknown; | ||
export type U2o<U> = IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; | ||
/** | ||
@@ -12,2 +20,2 @@ * Convert unknown to object. | ||
*/ | ||
export declare function u2o<U>(u: U): U2o<U>; | ||
export declare function u2o<U>(u: U): IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; |
@@ -0,1 +1,2 @@ | ||
import { Converter } from './utils'; | ||
/** | ||
@@ -7,4 +8,8 @@ * Do not declare this function with overloading. | ||
/** | ||
* Converts `u` to a string, and if `u` is not a string, calls the conversion function or returns an undefined. | ||
* Convert `what` to a string, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a string, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2s<U, R = undefined>(u: U, converter?: (u: U) => R): import("./utils").IfAnyOrUnknown<U, string | R, U extends string ? U : R>; | ||
export declare function u2s<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>): import("./utils").IfAnyOrUnknown<U, string | R, U extends string ? U : R>; |
@@ -8,7 +8,11 @@ import { u2x } from './utils'; | ||
/** | ||
* Converts `u` to a string, and if `u` is not a string, calls the conversion function or returns an undefined. | ||
* Convert `what` to a string, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a string, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2s(u, converter) { | ||
return u2x('string', u, converter); | ||
export function u2s(what, defaultValueOrConverter) { | ||
return u2x('string', what, defaultValueOrConverter); | ||
} | ||
//# sourceMappingURL=u2s.js.map |
@@ -1,17 +0,13 @@ | ||
export type IfAnyOrUnknown<T, Y, N = T> = unknown extends T ? Y : N; | ||
/** | ||
* For each type of a union `U`, if it is extended from `E`, it is kept, otherwise it is converted to `R`, | ||
* and finally each mapped type is merged into a new union. | ||
* | ||
* For example: | ||
* | ||
* - `U2x<number, 1 | 2, null>` results `1 | 2` | ||
* - `U2x<number, 'a', null>` results `null` | ||
* - `U2x<number, 1 | 2 | 'a', null>` results `1 | 2 | null` | ||
* - `U2x<number, unknown, null>` results `number | null` | ||
* | ||
* NOTE: If `U` is `any` or `unknown`, return the `P | R` directly. | ||
* If `U` is `any` or `unknown`, returns `Y` else returns `N`. | ||
*/ | ||
export type U2x<E, U, R = unknown> = IfAnyOrUnknown<U, E | R, U extends E ? U : R>; | ||
type TypeMap = { | ||
export type IfAnyOrUnknown<U, Y, N = U> = unknown extends U ? Y : N; | ||
/** | ||
* If `U` is `never`, returns `Y` else returns `N`. | ||
*/ | ||
export type IfNever<U, Y, N = U> = [U] extends [never] ? Y : N; | ||
/** | ||
* Maps a JavaScript typeof string to a real TypeScript type. | ||
*/ | ||
export type JTypes = { | ||
string: string; | ||
@@ -22,6 +18,17 @@ number: number; | ||
/** | ||
* Converts `u` to a the `t` type, calls the conversion function or returns an undefined. | ||
* A dirty object, any propertis can be access and got an unknow value. | ||
*/ | ||
export declare function u2x<T extends keyof TypeMap, U, R = undefined>(t: T, u: U, converter?: (u: U) => R): IfAnyOrUnknown<U, R | TypeMap[T], U extends TypeMap[T] ? U : R>; | ||
export type DirtyObject = Record<PropertyKey, unknown>; | ||
export {}; | ||
/** | ||
* A conversion function that converts `value` to any you want. | ||
*/ | ||
export type Converter<V, R> = (value: V) => R; | ||
/** | ||
* If `what` matching `type`, return `what` directly, otherwise try to call a conversion function and return. | ||
* If the conversion function is also not provided, the default value (may be undefined) will be returned. | ||
* | ||
* @param type Expected type. | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export declare function u2x<T extends keyof JTypes, U, R = undefined>(type: T, what: U, defaultValueOrConverter?: R | ((u: U) => R)): IfAnyOrUnknown<U, R | JTypes[T], U extends JTypes[T] ? U : R>; |
/** | ||
* Converts `u` to a the `t` type, calls the conversion function or returns an undefined. | ||
* Convert something, whether it is a value or already a conversion function, to a converter. | ||
* | ||
* NOTE: In fact, even if value type is a 'function', we still cannot assert that it is a `Converter`, | ||
* as it may also be a `() => void` that cannot receiving any parameters. | ||
* Anyway, we force it to be treated as a `Convert`, if it is a function. | ||
* TypeScript does not support type exclusion, otherwise defining `R` as `Exclude<any, Function>` would be better. | ||
* | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
* @returns A converter function. | ||
*/ | ||
export function u2x(t, u, converter) { | ||
return (typeof u === t ? u : converter === null || converter === void 0 ? void 0 : converter(u)); | ||
var toConverter = function (defaultValueOrConverter) { | ||
return (typeof defaultValueOrConverter === 'function' ? defaultValueOrConverter : function () { return defaultValueOrConverter; }); | ||
}; | ||
/** | ||
* If `what` matching `type`, return `what` directly, otherwise try to call a conversion function and return. | ||
* If the conversion function is also not provided, the default value (may be undefined) will be returned. | ||
* | ||
* @param type Expected type. | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2x(type, what, defaultValueOrConverter) { | ||
return (typeof what === type ? what : toConverter(defaultValueOrConverter)(what)); | ||
} | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "u2x", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "A suite of utilities for converting unknown data to desired type.", | ||
@@ -38,3 +38,7 @@ "main": "dist/cjs/index.js", | ||
"typescript": "^5.1.6" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/YanagiEiichi/u2x.git" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# u2x | ||
# u2x · [](LICENSE.txt) [](https://codecov.io/gh/YanagiEiichi/u2x) | ||
@@ -3,0 +3,0 @@ A suite of utilities for converting unknown data to desired type. |
@@ -7,3 +7,3 @@ import { u2a, u2n } from '..'; | ||
expect(r1).toMatchObject([]); | ||
true as AssertTrue<IsEquals<unknown[], typeof r1>>; | ||
true as AssertTrue<IsEquals<never[], typeof r1>>; | ||
@@ -54,1 +54,14 @@ const r2 = u2a([1]); | ||
}); | ||
test('Array or not Array', () => { | ||
let data: number[] | undefined; | ||
u2a(data, (v) => { | ||
true as AssertTrue<IsEquals<number, typeof v>>; | ||
}); | ||
}); | ||
test('Never an array', () => { | ||
u2a(1, (v) => { | ||
true as AssertTrue<IsEquals<never, typeof v>>; | ||
}); | ||
}); |
@@ -1,10 +0,54 @@ | ||
import { U2x } from '../utils'; | ||
import { u2x } from '../utils'; | ||
import { AssertTrue, IsEquals } from './libs'; | ||
test('The type definition of U2x', () => { | ||
true as | ||
| AssertTrue<IsEquals<1 | 2, U2x<number, 1 | 2, null>>> | ||
| AssertTrue<IsEquals<null, U2x<number, 'a', null>>> | ||
| AssertTrue<IsEquals<1 | 2 | null, U2x<number, 1 | 2 | 'a', null>>> | ||
| AssertTrue<IsEquals<number | null, U2x<number, unknown, null>>>; | ||
test('Strict number type should be preserved', () => { | ||
const r = u2x('number', 1 as 1 | 2); | ||
expect(r).toBe(1); | ||
true as AssertTrue<IsEquals<1 | 2, typeof r>>; | ||
}); | ||
test('Strict string type should be preserved', () => { | ||
const r = u2x('string', 'a' as 'a' | 'b'); | ||
expect(r).toBe('a'); | ||
true as AssertTrue<IsEquals<'a' | 'b', typeof r>>; | ||
}); | ||
test('Filter number types, and convert other types to undefined', () => { | ||
const r = u2x('number', 1 as 1 | 'a' | true | 2 | 'b' | false | null | { a: 1 }); | ||
expect(r).toBe(1); | ||
true as AssertTrue<IsEquals<1 | 2 | undefined, typeof r>>; | ||
}); | ||
test('Filter string types, and convert other types to undefined', () => { | ||
const r = u2x('string', 'a' as 1 | 'a' | true | 2 | 'b' | false | null | { a: 1 }); | ||
expect(r).toBe('a'); | ||
true as AssertTrue<IsEquals<'a' | 'b' | undefined, typeof r>>; | ||
}); | ||
test('A `unknown` type convert to `string`', () => { | ||
const r1 = u2x('string', 'a' as unknown); | ||
expect(r1).toBe('a'); | ||
true as AssertTrue<IsEquals<string | undefined, typeof r1>>; | ||
const r2 = u2x('string', 1 as unknown); | ||
expect(r2).toBe(undefined); | ||
true as AssertTrue<IsEquals<string | undefined, typeof r2>>; | ||
const r3 = u2x('string', 1 as unknown, () => null); | ||
expect(r3).toBe(null); | ||
true as AssertTrue<IsEquals<string | null, typeof r3>>; | ||
}); | ||
test('A `unknown` type convert to `number`', () => { | ||
const r1 = u2x('number', 'a' as unknown); | ||
expect(r1).toBe(undefined); | ||
true as AssertTrue<IsEquals<number | undefined, typeof r1>>; | ||
const r2 = u2x('number', 1 as unknown); | ||
expect(r2).toBe(1); | ||
true as AssertTrue<IsEquals<number | undefined, typeof r2>>; | ||
const r3 = u2x('number', 'a' as unknown, () => null); | ||
expect(r3).toBe(null); | ||
true as AssertTrue<IsEquals<number | null, typeof r3>>; | ||
}); |
@@ -1,13 +0,16 @@ | ||
import { IfAnyOrUnknown } from './utils'; | ||
import { IfAnyOrUnknown, IfNever } from './utils'; | ||
export type ArrayItem<T> = T extends readonly (infer U)[] ? U : unknown; | ||
/** | ||
* Convert any type to array. | ||
* Try to extract all explicit array types from `U`, if `never` fallback to an `unknown[]`. | ||
*/ | ||
export type ToArray<U> = IfAnyOrUnknown< | ||
// Is the `U` a unsafe type? (`any` or `unknown`) | ||
U, | ||
// Yes, `U` is a unsafe type, return a unsafe array as the result[] | ||
unknown[], | ||
// No, `U` is a safe type, extract array types, and fallback to unknown array. | ||
IfNever<Extract<U, readonly unknown[]>, never[]> | ||
>; | ||
export type U2a<U, R> = | ||
// Check `F` is `never` or not. | ||
[R] extends [never] | ||
? // Yes `F` is a `never`, no callback function provided. | ||
IfAnyOrUnknown<U, unknown, U extends readonly unknown[] ? U : unknown[]> | ||
: // No, `F` is not a `never`. | ||
IfAnyOrUnknown<R, unknown>[]; | ||
/** | ||
@@ -18,7 +21,17 @@ * Converts unknown to an array. | ||
*/ | ||
export function u2a<U, R = never>(u: U, callbackfn?: (item: ArrayItem<U>) => R): U2a<U, R> { | ||
export function u2a<U, R = never>(u: U, callbackfn?: (item: ToArray<U>[number]) => R) { | ||
const a = u instanceof Array ? u : []; | ||
if (!callbackfn) return a as U2a<U, R>; | ||
// Do not use `a.map(...)`, because `a.map` may be dirty. | ||
return Array.prototype.map.call(a, (v) => callbackfn(v)) as U2a<U, R>; | ||
return ( | ||
callbackfn | ||
? // Do not use `a.map(...)`, because `a.map` may be dirty. | ||
Array.prototype.map.call(a, (v) => callbackfn(v)) | ||
: a | ||
) as IfNever< | ||
// Is the `R` `never`? | ||
R, | ||
// Yes `R` is a `never`, that means no callback function provided. | ||
ToArray<U>, | ||
// No, `U` is not a `never`, use an array of callback return type as the result. | ||
IfAnyOrUnknown<R, unknown>[] | ||
>; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { u2x } from './utils'; | ||
import { Converter, u2x } from './utils'; | ||
@@ -10,6 +10,10 @@ /** | ||
/** | ||
* Converts `u` to a boolean, and if `u` is not a boolean, calls the conversion function or returns an undefined. | ||
* Convert `what` to a boolean, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a boolean, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2b<U, R = undefined>(u: U, converter?: (u: U) => R) { | ||
return u2x('boolean', u, converter); | ||
export function u2b<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>) { | ||
return u2x('boolean', what, defaultValueOrConverter); | ||
} |
@@ -1,2 +0,2 @@ | ||
import { u2x } from './utils'; | ||
import { Converter, u2x } from './utils'; | ||
@@ -10,6 +10,10 @@ /** | ||
/** | ||
* Converts `u` to a number, and if `u` is not a number, calls the conversion function or returns an undefined. | ||
* Convert `what` to a number, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a number, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2n<U, R = undefined>(u: U, converter?: (u: U) => R) { | ||
return u2x('number', u, converter); | ||
export function u2n<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>) { | ||
return u2x('number', what, defaultValueOrConverter); | ||
} |
import { IfAnyOrUnknown, DirtyObject } from './utils'; | ||
/** | ||
* Convert any type to object by folloing steps: | ||
* | ||
* - If `U` is a `string`, returns a `String` object. | ||
* - If `U` is a `number`, returns a `Number` object. | ||
* - If `U` is a `boolean`, returns a `Boolean` object. | ||
* - If `U` is an `object`, * returns `U` itself. | ||
* - Otherwise returns an `unknown`. | ||
*/ | ||
export type ToObject<U> = U extends object | ||
@@ -13,4 +22,2 @@ ? U | ||
export type U2o<U> = IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; | ||
/** | ||
@@ -24,4 +31,4 @@ * Convert unknown to object. | ||
*/ | ||
export function u2o<U>(u: U): U2o<U> { | ||
return Object(u); | ||
export function u2o<U>(u: U) { | ||
return Object(u) as IfAnyOrUnknown<U, unknown, ToObject<U>> & DirtyObject; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { u2x } from './utils'; | ||
import { Converter, u2x } from './utils'; | ||
@@ -10,6 +10,10 @@ /** | ||
/** | ||
* Converts `u` to a string, and if `u` is not a string, calls the conversion function or returns an undefined. | ||
* Convert `what` to a string, you can provide a custom conversion function or a default value. | ||
* By default, if `what` is not a string, a `undefined` will be returned. | ||
* | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2s<U, R = undefined>(u: U, converter?: (u: U) => R) { | ||
return u2x('string', u, converter); | ||
export function u2s<U, R = undefined>(what: U, defaultValueOrConverter?: R | Converter<U, R>) { | ||
return u2x('string', what, defaultValueOrConverter); | ||
} |
@@ -1,19 +0,15 @@ | ||
export type IfAnyOrUnknown<T, Y, N = T> = unknown extends T ? Y : N; | ||
/** | ||
* If `U` is `any` or `unknown`, returns `Y` else returns `N`. | ||
*/ | ||
export type IfAnyOrUnknown<U, Y, N = U> = unknown extends U ? Y : N; | ||
/** | ||
* For each type of a union `U`, if it is extended from `E`, it is kept, otherwise it is converted to `R`, | ||
* and finally each mapped type is merged into a new union. | ||
* | ||
* For example: | ||
* | ||
* - `U2x<number, 1 | 2, null>` results `1 | 2` | ||
* - `U2x<number, 'a', null>` results `null` | ||
* - `U2x<number, 1 | 2 | 'a', null>` results `1 | 2 | null` | ||
* - `U2x<number, unknown, null>` results `number | null` | ||
* | ||
* NOTE: If `U` is `any` or `unknown`, return the `P | R` directly. | ||
* If `U` is `never`, returns `Y` else returns `N`. | ||
*/ | ||
export type U2x<E, U, R = unknown> = IfAnyOrUnknown<U, E | R, U extends E ? U : R>; | ||
export type IfNever<U, Y, N = U> = [U] extends [never] ? Y : N; | ||
type TypeMap = { | ||
/** | ||
* Maps a JavaScript typeof string to a real TypeScript type. | ||
*/ | ||
export type JTypes = { | ||
string: string; | ||
@@ -25,8 +21,46 @@ number: number; | ||
/** | ||
* Converts `u` to a the `t` type, calls the conversion function or returns an undefined. | ||
* A dirty object, any propertis can be access and got an unknow value. | ||
*/ | ||
export function u2x<T extends keyof TypeMap, U, R = undefined>(t: T, u: U, converter?: (u: U) => R) { | ||
return (typeof u === t ? u : converter?.(u)) as U2x<TypeMap[T], U, R>; | ||
export type DirtyObject = Record<PropertyKey, unknown>; | ||
/** | ||
* A conversion function that converts `value` to any you want. | ||
*/ | ||
export type Converter<V, R> = (value: V) => R; | ||
/** | ||
* Convert something, whether it is a value or already a conversion function, to a converter. | ||
* | ||
* NOTE: In fact, even if value type is a 'function', we still cannot assert that it is a `Converter`, | ||
* as it may also be a `() => void` that cannot receiving any parameters. | ||
* Anyway, we force it to be treated as a `Convert`, if it is a function. | ||
* TypeScript does not support type exclusion, otherwise defining `R` as `Exclude<any, Function>` would be better. | ||
* | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
* @returns A converter function. | ||
*/ | ||
const toConverter = <R, V>(defaultValueOrConverter: R | Converter<V, R>) => { | ||
return ( | ||
typeof defaultValueOrConverter === 'function' ? defaultValueOrConverter : () => defaultValueOrConverter | ||
) as Converter<V, R>; | ||
}; | ||
/** | ||
* If `what` matching `type`, return `what` directly, otherwise try to call a conversion function and return. | ||
* If the conversion function is also not provided, the default value (may be undefined) will be returned. | ||
* | ||
* @param type Expected type. | ||
* @param what Input value. | ||
* @param defaultValueOrConverter A default value or a converter function. | ||
*/ | ||
export function u2x<T extends keyof JTypes, U, R = undefined>( | ||
type: T, | ||
what: U, | ||
defaultValueOrConverter?: R | ((u: U) => R), | ||
) { | ||
return (typeof what === type ? what : toConverter(defaultValueOrConverter)(what)) as IfAnyOrUnknown< | ||
U, | ||
JTypes[T] | R, | ||
U extends JTypes[T] ? U : R | ||
>; | ||
} | ||
export type DirtyObject = Record<PropertyKey, unknown>; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
50875
61
1048
0
1