-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
box.ts
71 lines (69 loc) · 1.9 KB
/
box.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import type { IsBigint } from '../bigint/is_bigint.js'
import type { IsBoolean } from '../boolean/is_boolean.js'
import type { IsFunction } from '../function/is_function.js'
import type { IsNumber } from '../number/is_number.js'
import type { IsObject } from '../object/is_object.js'
import type { IsString } from '../string/is_string.js'
import type { IsSymbol } from '../symbol/is_symbol.js'
import type { $Else, $SelectionBranch, $Then } from '../type_plus/branch/$selection.js'
/**
* ⚗️ *transform*
* 🔢 *customizable*
*
* Converts primitive types to their boxed types.
*
* @typeParam Options['$notBoxable'] return type when `T` is not boxable. Defaults to `never`.
*
* @example
* ```ts
* Box<number> // Number
* Box<object> // Object
* Box<string> // String
* Box<'abc'> // String
*
* Box<undefined> // never
* ```
*/
export type Box<T, Options extends Box.Options = Box.DefaultOptions> = IsFunction<T, IsFunction.$Branch> extends infer R
? R extends $Then
? Function
: IsObject<T, IsObject.$Branch<{ exact: true }>> extends infer R
? R extends $Then
? Object
: T extends Record<any, any>
? T
: IsBoolean<T, $SelectionBranch> extends infer R
? R extends $Then
? Boolean
: R extends $Else
? IsNumber<T, IsNumber.$Branch> extends infer R
? R extends $Then
? Number
: R extends $Else
? IsString<
T,
{
$then: String
$else: IsSymbol<
T,
{
$then: Symbol
$else: IsBigint<T, { $then: BigInt; $else: Options['$notBoxable'] }>
}
>
}
>
: never
: never
: never
: never
: never
: never
export namespace Box {
export type Options = {
$notBoxable?: unknown
}
export interface DefaultOptions {
$notBoxable: never
}
}