@solana/nominal-types 6.3.1 → 6.3.2-canary-20260313112147
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/package.json +3 -2
- package/src/index.ts +142 -0
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/nominal-types",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.2-canary-20260313112147",
|
|
4
4
|
"description": "Type utilties for creating nominal/branded types in TypeScript",
|
|
5
5
|
"homepage": "https://www.solanakit.com/api#solananominal-types",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
7
7
|
"type": "commonjs",
|
|
8
8
|
"files": [
|
|
9
|
-
"./dist/"
|
|
9
|
+
"./dist/",
|
|
10
|
+
"./src/"
|
|
10
11
|
],
|
|
11
12
|
"sideEffects": false,
|
|
12
13
|
"keywords": [
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This package contains type utilities for creating nominal types in TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* @example Brands, compression, and encodings can be combined
|
|
5
|
+
* ```ts
|
|
6
|
+
* const encodedCompressedString = 'abc' as Brand<
|
|
7
|
+
* EncodedString<CompressedData<'abc', 'zstd'>, 'base64'>,
|
|
8
|
+
* 'Base64ZstdCompressedData'
|
|
9
|
+
* >;
|
|
10
|
+
*
|
|
11
|
+
* encodedCompressedString satisfies Brand<'abc', 'Base64ZstdCompressedData'>; // OK
|
|
12
|
+
* encodedCompressedString satisfies Brand<string, 'Base64ZstdCompressedData'>; // OK
|
|
13
|
+
* encodedCompressedString satisfies CompressedData<'abc', 'zstd'>; // OK
|
|
14
|
+
* encodedCompressedString satisfies CompressedData<string, 'zstd'>; // OK
|
|
15
|
+
* encodedCompressedString satisfies EncodedString<'abc', 'base64'>; // OK
|
|
16
|
+
* encodedCompressedString satisfies EncodedString<string, 'base64'>; // OK
|
|
17
|
+
* encodedCompressedString satisfies EncodedString<string, 'base58'>; // ERROR
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
type AffinePointValidity = 'invalid' | 'valid';
|
|
24
|
+
type CompressionFormat = 'zstd';
|
|
25
|
+
type StringEncoding = 'base58' | 'base64';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Use this to produce a new type that satisfies the original type, but adds extra type information
|
|
29
|
+
* that marks the type as being an affine point over a field that either lies on a given curve
|
|
30
|
+
* (is valid) or does not (is invalid).
|
|
31
|
+
*
|
|
32
|
+
* @typeParam T - The underlying type
|
|
33
|
+
* @typeParam TValidity - Whether the point is valid or invalid
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const address = 'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92';
|
|
38
|
+
* const onCurveAddress = address as AffinePoint<typeof address, 'valid'>;
|
|
39
|
+
*
|
|
40
|
+
* onCurveAddress satisfies AffinePoint<'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92', 'valid'>; // OK
|
|
41
|
+
* onCurveAddress satisfies AffinePoint<string, 'valid'>; // OK
|
|
42
|
+
* onCurveAddress satisfies AffinePoint<string, 'invalid'>; // ERROR
|
|
43
|
+
* address satisfies AffinePoint<string, 'valid'>; // ERROR
|
|
44
|
+
* address satisfies AffinePoint<string, 'invalid'>; // ERROR
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export type AffinePoint<T, TValidity extends AffinePointValidity> = NominalType<'affinePoint', TValidity> & T;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Use this to produce a new type that satisfies the original type, but not the other way around.
|
|
51
|
+
* That is to say, the branded type is acceptable wherever the original type is specified, but
|
|
52
|
+
* wherever the branded type is specified, the original type will be insufficient.
|
|
53
|
+
*
|
|
54
|
+
* You can use this to create specialized instances of strings, numbers, objects, and more which
|
|
55
|
+
* you would like to assert are special in some way (eg. numbers that are non-negative, strings
|
|
56
|
+
* which represent the names of foods, objects that have passed validation).
|
|
57
|
+
*
|
|
58
|
+
* @typeParam T - The base type to brand
|
|
59
|
+
* @typeParam TBrandName - A string that identifies a particular brand. Branded types with identical
|
|
60
|
+
* names will satisfy each other so long as their base types satisfy each other. Branded types with
|
|
61
|
+
* different names will never satisfy each other.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const unverifiedName = 'Alice';
|
|
66
|
+
* const verifiedName = unverifiedName as Brand<'Alice', 'VerifiedName'>;
|
|
67
|
+
*
|
|
68
|
+
* 'Alice' satisfies Brand<string, 'VerifiedName'>; // ERROR
|
|
69
|
+
* 'Alice' satisfies Brand<'Alice', 'VerifiedName'>; // ERROR
|
|
70
|
+
* unverifiedName satisfies Brand<string, 'VerifiedName'>; // ERROR
|
|
71
|
+
* verifiedName satisfies Brand<'Bob', 'VerifiedName'>; // ERROR
|
|
72
|
+
* verifiedName satisfies Brand<'Alice', 'VerifiedName'>; // OK
|
|
73
|
+
* verifiedName satisfies Brand<string, 'VerifiedName'>; // OK
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export type Brand<T, TBrandName extends string> = NominalType<'brand', TBrandName> & T;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Use this to produce a new type that satisfies the original type, but adds extra type information
|
|
80
|
+
* that marks the type as containing compressed data.
|
|
81
|
+
*
|
|
82
|
+
* @typeParam T - The base type to mark as representing compressed data
|
|
83
|
+
* @typeParam TFormat - The compression format of the underlying data
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const untaggedData = new Uint8Array([/* ... *\/]);
|
|
88
|
+
* const compressedData = untaggedData as CompressedData<typeof untaggedData, 'zstd'>;
|
|
89
|
+
*
|
|
90
|
+
* compressedData satisfies CompressedData<Uint8Array, 'zstd'>; // OK
|
|
91
|
+
* untaggedData satisfies CompressedData<Uint8Array, 'zstd'>; // ERROR
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export type CompressedData<T, TFormat extends CompressionFormat> = NominalType<'compressionFormat', TFormat> & T;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Use this to produce a new type that satisfies the original string type, but adds extra type
|
|
98
|
+
* information that marks the string as being encoded in a particular format.
|
|
99
|
+
*
|
|
100
|
+
* @typeParam T - The underlying string type
|
|
101
|
+
* @typeParam TEncoding - The encoding format of the string
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* const untaggedString = 'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92';
|
|
106
|
+
* const encodedString = untaggedString as EncodedString<typeof untaggedString, 'base58'>;
|
|
107
|
+
*
|
|
108
|
+
* encodedString satisfies EncodedString<'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92', 'base58'>; // OK
|
|
109
|
+
* encodedString satisfies EncodedString<string, 'base58'>; // OK
|
|
110
|
+
* encodedString satisfies EncodedString<string, 'base64'>; // ERROR
|
|
111
|
+
* untaggedString satisfies EncodedString<string, 'base58'>; // ERROR
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export type EncodedString<T extends string, TEncoding extends StringEncoding> = NominalType<
|
|
115
|
+
'stringEncoding',
|
|
116
|
+
TEncoding
|
|
117
|
+
> &
|
|
118
|
+
T;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Use this to produce a nominal type.
|
|
122
|
+
*
|
|
123
|
+
* This can be intersected with other base types to produce custom branded types.
|
|
124
|
+
*
|
|
125
|
+
* @typeParam TKey - The name of the nominal type. This distinguishes one nominal type from another.
|
|
126
|
+
* @typeParam TMarker - The type of the value the nominal type can take.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* type SweeteningSubstance = 'aspartame' | 'cane-sugar' | 'stevia';
|
|
131
|
+
* type Sweetener<T extends SweeteningSubstance> = NominalType<'sweetener', T>;
|
|
132
|
+
*
|
|
133
|
+
* // This function accepts sweetened foods, except those with aspartame.
|
|
134
|
+
* declare function eat(food: string & Sweetener<Exclude<SweeteningSubstance, 'aspartame'>>): void;
|
|
135
|
+
*
|
|
136
|
+
* const artificiallySweetenedDessert = 'ice-cream' as string & Sweetener<'aspartame'>;
|
|
137
|
+
* eat(artificiallySweetenedDessert); // ERROR
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export type NominalType<TKey extends string, TMarker extends string> = {
|
|
141
|
+
readonly [K in `__${TKey}:@solana/kit`]: TMarker;
|
|
142
|
+
};
|