@tinybirdco/sdk 0.0.54 → 0.0.56

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.
@@ -1,226 +1,424 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { t, isTypeValidator, getTinybirdType, getModifiers } from './types.js';
3
-
4
- describe('Type Validators (t.*)', () => {
5
- describe('Basic types', () => {
6
- it('generates String type', () => {
1
+ import { describe, it, expect, expectTypeOf } from "vitest";
2
+ import { t, isTypeValidator, getTinybirdType, getModifiers } from "./types.js";
3
+ import { defineDatasource } from "./datasource.js";
4
+ import { engine } from "./engines.js";
5
+ import type { InferRow } from "../infer/index.js";
6
+
7
+ describe("Type Validators (t.*)", () => {
8
+ describe("Basic types", () => {
9
+ it("generates String type", () => {
7
10
  const type = t.string();
8
- expect(type._tinybirdType).toBe('String');
11
+ expect(type._tinybirdType).toBe("String");
9
12
  });
10
13
 
11
- it('generates Int32 type', () => {
14
+ it("generates Int32 type", () => {
12
15
  const type = t.int32();
13
- expect(type._tinybirdType).toBe('Int32');
16
+ expect(type._tinybirdType).toBe("Int32");
14
17
  });
15
18
 
16
- it('generates DateTime type', () => {
19
+ it("generates DateTime type", () => {
17
20
  const type = t.dateTime();
18
- expect(type._tinybirdType).toBe('DateTime');
21
+ expect(type._tinybirdType).toBe("DateTime");
19
22
  });
20
23
 
21
- it('generates DateTime with timezone', () => {
22
- const type = t.dateTime('UTC');
24
+ it("generates DateTime with timezone", () => {
25
+ const type = t.dateTime("UTC");
23
26
  expect(type._tinybirdType).toBe("DateTime('UTC')");
24
27
  });
25
28
 
26
- it('generates Bool type', () => {
29
+ it("generates Bool type", () => {
27
30
  const type = t.bool();
28
- expect(type._tinybirdType).toBe('Bool');
31
+ expect(type._tinybirdType).toBe("Bool");
29
32
  });
30
33
 
31
- it('generates UUID type', () => {
34
+ it("generates UUID type", () => {
32
35
  const type = t.uuid();
33
- expect(type._tinybirdType).toBe('UUID');
36
+ expect(type._tinybirdType).toBe("UUID");
34
37
  });
35
38
 
36
- it('generates Float64 type', () => {
39
+ it("generates Float64 type", () => {
37
40
  const type = t.float64();
38
- expect(type._tinybirdType).toBe('Float64');
41
+ expect(type._tinybirdType).toBe("Float64");
39
42
  });
40
43
 
41
- it('generates UInt64 type', () => {
44
+ it("generates UInt64 type", () => {
42
45
  const type = t.uint64();
43
- expect(type._tinybirdType).toBe('UInt64');
46
+ expect(type._tinybirdType).toBe("UInt64");
44
47
  });
45
48
  });
46
49
 
47
- describe('Nullable modifier', () => {
48
- it('wraps type in Nullable', () => {
50
+ describe("Nullable modifier", () => {
51
+ it("wraps type in Nullable", () => {
49
52
  const type = t.string().nullable();
50
- expect(type._tinybirdType).toBe('Nullable(String)');
53
+ expect(type._tinybirdType).toBe("Nullable(String)");
51
54
  });
52
55
 
53
- it('wraps Int32 in Nullable', () => {
56
+ it("wraps Int32 in Nullable", () => {
54
57
  const type = t.int32().nullable();
55
- expect(type._tinybirdType).toBe('Nullable(Int32)');
58
+ expect(type._tinybirdType).toBe("Nullable(Int32)");
56
59
  });
57
60
 
58
- it('sets nullable modifier', () => {
61
+ it("sets nullable modifier", () => {
59
62
  const type = t.string().nullable();
60
63
  expect(type._modifiers.nullable).toBe(true);
61
64
  });
62
65
  });
63
66
 
64
- describe('LowCardinality modifier', () => {
65
- it('wraps type in LowCardinality', () => {
67
+ describe("LowCardinality modifier", () => {
68
+ it("wraps type in LowCardinality", () => {
66
69
  const type = t.string().lowCardinality();
67
- expect(type._tinybirdType).toBe('LowCardinality(String)');
70
+ expect(type._tinybirdType).toBe("LowCardinality(String)");
68
71
  });
69
72
 
70
- it('sets lowCardinality modifier', () => {
73
+ it("sets lowCardinality modifier", () => {
71
74
  const type = t.string().lowCardinality();
72
75
  expect(type._modifiers.lowCardinality).toBe(true);
73
76
  });
74
77
  });
75
78
 
76
- describe('LowCardinality + Nullable ordering', () => {
77
- it('generates LowCardinality(Nullable(X)) when chaining .lowCardinality().nullable()', () => {
79
+ describe("LowCardinality + Nullable ordering", () => {
80
+ it("generates LowCardinality(Nullable(X)) when chaining .lowCardinality().nullable()", () => {
78
81
  const type = t.string().lowCardinality().nullable();
79
- expect(type._tinybirdType).toBe('LowCardinality(Nullable(String))');
82
+ expect(type._tinybirdType).toBe("LowCardinality(Nullable(String))");
80
83
  });
81
84
 
82
- it('generates LowCardinality(Nullable(X)) when chaining .nullable().lowCardinality()', () => {
85
+ it("generates LowCardinality(Nullable(X)) when chaining .nullable().lowCardinality()", () => {
83
86
  const type = t.string().nullable().lowCardinality();
84
- expect(type._tinybirdType).toBe('LowCardinality(Nullable(String))');
87
+ expect(type._tinybirdType).toBe("LowCardinality(Nullable(String))");
85
88
  });
86
89
 
87
- it('preserves both modifiers when chained', () => {
90
+ it("preserves both modifiers when chained", () => {
88
91
  const type = t.string().lowCardinality().nullable();
89
92
  expect(type._modifiers.lowCardinality).toBe(true);
90
93
  expect(type._modifiers.nullable).toBe(true);
91
94
  });
92
95
  });
93
96
 
94
- describe('Default values', () => {
95
- it('sets hasDefault modifier', () => {
96
- const type = t.string().default('test');
97
+ describe("Default values", () => {
98
+ it("sets hasDefault modifier", () => {
99
+ const type = t.string().default("test");
97
100
  expect(type._modifiers.hasDefault).toBe(true);
98
101
  });
99
102
 
100
- it('stores defaultValue in modifiers', () => {
101
- const type = t.string().default('test');
102
- expect(type._modifiers.defaultValue).toBe('test');
103
+ it("stores defaultValue in modifiers", () => {
104
+ const type = t.string().default("test");
105
+ expect(type._modifiers.defaultValue).toBe("test");
103
106
  });
104
107
 
105
- it('works with numeric defaults', () => {
108
+ it("works with numeric defaults", () => {
106
109
  const type = t.int32().default(42);
107
110
  expect(type._modifiers.defaultValue).toBe(42);
108
111
  });
109
112
  });
110
113
 
111
- describe('Codec modifier', () => {
112
- it('sets codec in modifiers', () => {
113
- const type = t.string().codec('LZ4');
114
- expect(type._modifiers.codec).toBe('LZ4');
114
+ describe("Codec modifier", () => {
115
+ it("sets codec in modifiers", () => {
116
+ const type = t.string().codec("LZ4");
117
+ expect(type._modifiers.codec).toBe("LZ4");
115
118
  });
116
119
  });
117
120
 
118
- describe('jsonPath modifier', () => {
119
- it('sets jsonPath in modifiers', () => {
120
- const type = t.string().jsonPath('$.payload.id');
121
- expect(type._modifiers.jsonPath).toBe('$.payload.id');
121
+ describe("jsonPath modifier", () => {
122
+ it("sets jsonPath in modifiers", () => {
123
+ const type = t.string().jsonPath("$.payload.id");
124
+ expect(type._modifiers.jsonPath).toBe("$.payload.id");
122
125
  });
123
126
 
124
- it('supports chaining with other modifiers', () => {
125
- const type = t.string().nullable().jsonPath('$.user.name');
126
- expect(type._tinybirdType).toBe('Nullable(String)');
127
+ it("supports chaining with other modifiers", () => {
128
+ const type = t.string().nullable().jsonPath("$.user.name");
129
+ expect(type._tinybirdType).toBe("Nullable(String)");
127
130
  expect(type._modifiers.nullable).toBe(true);
128
- expect(type._modifiers.jsonPath).toBe('$.user.name');
131
+ expect(type._modifiers.jsonPath).toBe("$.user.name");
129
132
  });
130
133
  });
131
134
 
132
- describe('Complex types', () => {
133
- it('generates Array type', () => {
135
+ describe("Complex types", () => {
136
+ it("generates Array type", () => {
134
137
  const type = t.array(t.string());
135
- expect(type._tinybirdType).toBe('Array(String)');
138
+ expect(type._tinybirdType).toBe("Array(String)");
136
139
  });
137
140
 
138
- it('generates nested Array type', () => {
141
+ it("generates nested Array type", () => {
139
142
  const type = t.array(t.int32());
140
- expect(type._tinybirdType).toBe('Array(Int32)');
143
+ expect(type._tinybirdType).toBe("Array(Int32)");
141
144
  });
142
145
 
143
- it('generates Map type', () => {
146
+ it("generates Map type", () => {
144
147
  const type = t.map(t.string(), t.int32());
145
- expect(type._tinybirdType).toBe('Map(String, Int32)');
148
+ expect(type._tinybirdType).toBe("Map(String, Int32)");
146
149
  });
147
150
 
148
- it('generates Decimal type', () => {
151
+ it("generates Decimal type", () => {
149
152
  const type = t.decimal(10, 2);
150
- expect(type._tinybirdType).toBe('Decimal(10, 2)');
153
+ expect(type._tinybirdType).toBe("Decimal(10, 2)");
151
154
  });
152
155
 
153
- it('generates FixedString type', () => {
156
+ it("generates FixedString type", () => {
154
157
  const type = t.fixedString(3);
155
- expect(type._tinybirdType).toBe('FixedString(3)');
158
+ expect(type._tinybirdType).toBe("FixedString(3)");
156
159
  });
157
160
 
158
- it('generates Tuple type', () => {
161
+ it("generates Tuple type", () => {
159
162
  const type = t.tuple(t.string(), t.int32());
160
- expect(type._tinybirdType).toBe('Tuple(String, Int32)');
163
+ expect(type._tinybirdType).toBe("Tuple(String, Int32)");
161
164
  });
162
165
 
163
- it('generates DateTime64 type', () => {
166
+ it("generates DateTime64 type", () => {
164
167
  const type = t.dateTime64(3);
165
- expect(type._tinybirdType).toBe('DateTime64(3)');
168
+ expect(type._tinybirdType).toBe("DateTime64(3)");
166
169
  });
167
170
 
168
- it('generates DateTime64 with timezone', () => {
169
- const type = t.dateTime64(3, 'UTC');
171
+ it("generates DateTime64 with timezone", () => {
172
+ const type = t.dateTime64(3, "UTC");
170
173
  expect(type._tinybirdType).toBe("DateTime64(3, 'UTC')");
171
174
  });
172
175
  });
173
176
 
174
- describe('Helper functions', () => {
175
- it('isTypeValidator returns true for validators', () => {
177
+ describe("Helper functions", () => {
178
+ it("isTypeValidator returns true for validators", () => {
176
179
  expect(isTypeValidator(t.string())).toBe(true);
177
180
  });
178
181
 
179
- it('isTypeValidator returns false for non-validators', () => {
180
- expect(isTypeValidator('string')).toBe(false);
182
+ it("isTypeValidator returns false for non-validators", () => {
183
+ expect(isTypeValidator("string")).toBe(false);
181
184
  expect(isTypeValidator({})).toBe(false);
182
185
  expect(isTypeValidator(null)).toBe(false);
183
186
  });
184
187
 
185
- it('getTinybirdType returns type string', () => {
186
- expect(getTinybirdType(t.string())).toBe('String');
188
+ it("getTinybirdType returns type string", () => {
189
+ expect(getTinybirdType(t.string())).toBe("String");
187
190
  });
188
191
 
189
- it('getModifiers returns modifiers object', () => {
192
+ it("getModifiers returns modifiers object", () => {
190
193
  const modifiers = getModifiers(t.string().nullable());
191
194
  expect(modifiers.nullable).toBe(true);
192
195
  });
193
196
  });
194
197
 
195
- describe('Chained modifiers', () => {
196
- it('supports multiple modifiers', () => {
197
- const type = t.string().lowCardinality().default('test');
198
- expect(type._tinybirdType).toBe('LowCardinality(String)');
198
+ describe("Chained modifiers", () => {
199
+ it("supports multiple modifiers", () => {
200
+ const type = t.string().lowCardinality().default("test");
201
+ expect(type._tinybirdType).toBe("LowCardinality(String)");
199
202
  expect(type._modifiers.lowCardinality).toBe(true);
200
203
  expect(type._modifiers.hasDefault).toBe(true);
201
- expect(type._modifiers.defaultValue).toBe('test');
204
+ expect(type._modifiers.defaultValue).toBe("test");
202
205
  });
203
206
  });
204
207
 
205
- describe('Enum types', () => {
206
- it('generates Enum8 with value mapping', () => {
207
- const type = t.enum8('active', 'inactive', 'pending');
208
- expect(type._tinybirdType).toBe("Enum8('active' = 1, 'inactive' = 2, 'pending' = 3)");
208
+ describe("Enum types", () => {
209
+ it("generates Enum8 with value mapping", () => {
210
+ const type = t.enum8("active", "inactive", "pending");
211
+ expect(type._tinybirdType).toBe(
212
+ "Enum8('active' = 1, 'inactive' = 2, 'pending' = 3)",
213
+ );
209
214
  });
210
215
 
211
- it('generates Enum16 with value mapping', () => {
212
- const type = t.enum16('draft', 'published', 'archived');
213
- expect(type._tinybirdType).toBe("Enum16('draft' = 1, 'published' = 2, 'archived' = 3)");
216
+ it("generates Enum16 with value mapping", () => {
217
+ const type = t.enum16("draft", "published", "archived");
218
+ expect(type._tinybirdType).toBe(
219
+ "Enum16('draft' = 1, 'published' = 2, 'archived' = 3)",
220
+ );
214
221
  });
215
222
 
216
- it('escapes single quotes in enum values', () => {
217
- const type = t.enum8("it's ok", 'normal');
223
+ it("escapes single quotes in enum values", () => {
224
+ const type = t.enum8("it's ok", "normal");
218
225
  expect(type._tinybirdType).toBe("Enum8('it\\'s ok' = 1, 'normal' = 2)");
219
226
  });
220
227
 
221
- it('handles single enum value', () => {
222
- const type = t.enum8('only');
228
+ it("handles single enum value", () => {
229
+ const type = t.enum8("only");
223
230
  expect(type._tinybirdType).toBe("Enum8('only' = 1)");
224
231
  });
225
232
  });
233
+
234
+ describe("Custom type generics", () => {
235
+ // Branded/nominal type helpers for testing
236
+ type UserId = string & { readonly __brand: "UserId" };
237
+ type TraceId = string & { readonly __brand: "TraceId" };
238
+ type Timestamp = string & { readonly __brand: "Timestamp" };
239
+ type Count = number & { readonly __brand: "Count" };
240
+ type Price = number & { readonly __brand: "Price" };
241
+ type BigId = bigint & { readonly __brand: "BigId" };
242
+ type IsActive = boolean & { readonly __brand: "IsActive" };
243
+
244
+ describe("runtime behavior unchanged", () => {
245
+ it("string with generic produces same _tinybirdType", () => {
246
+ expect(t.string<UserId>()._tinybirdType).toBe(t.string()._tinybirdType);
247
+ expect(t.string<UserId>()._tinybirdType).toBe("String");
248
+ });
249
+
250
+ it("int32 with generic produces same _tinybirdType", () => {
251
+ expect(t.int32<Count>()._tinybirdType).toBe(t.int32()._tinybirdType);
252
+ });
253
+
254
+ it("uuid with generic produces same _tinybirdType", () => {
255
+ expect(t.uuid<TraceId>()._tinybirdType).toBe("UUID");
256
+ });
257
+
258
+ it("dateTime with generic produces same _tinybirdType", () => {
259
+ expect(t.dateTime<Timestamp>()._tinybirdType).toBe("DateTime");
260
+ expect(t.dateTime<Timestamp>("UTC")._tinybirdType).toBe(
261
+ "DateTime('UTC')",
262
+ );
263
+ });
264
+
265
+ it("bool with generic produces same _tinybirdType", () => {
266
+ expect(t.bool<IsActive>()._tinybirdType).toBe("Bool");
267
+ });
268
+
269
+ it("int128 with generic produces same _tinybirdType", () => {
270
+ expect(t.int128<BigId>()._tinybirdType).toBe("Int128");
271
+ });
272
+
273
+ it("decimal with generic produces same _tinybirdType", () => {
274
+ expect(t.decimal<Price>(10, 2)._tinybirdType).toBe("Decimal(10, 2)");
275
+ });
276
+
277
+ it("fixedString with generic produces same _tinybirdType", () => {
278
+ type CountryCode = string & { readonly __brand: "CountryCode" };
279
+ expect(t.fixedString<CountryCode>(2)._tinybirdType).toBe(
280
+ "FixedString(2)",
281
+ );
282
+ });
283
+ });
284
+
285
+ describe("modifiers work with custom generics", () => {
286
+ it("nullable", () => {
287
+ const v = t.string<UserId>().nullable();
288
+ expect(v._tinybirdType).toBe("Nullable(String)");
289
+ expect(v._modifiers.nullable).toBe(true);
290
+ });
291
+
292
+ it("lowCardinality", () => {
293
+ expect(t.string<UserId>().lowCardinality()._tinybirdType).toBe(
294
+ "LowCardinality(String)",
295
+ );
296
+ });
297
+
298
+ it("default", () => {
299
+ const v = t.string<UserId>().default("fallback" as UserId);
300
+ expect(v._modifiers.hasDefault).toBe(true);
301
+ expect(v._modifiers.defaultValue).toBe("fallback");
302
+ });
303
+ });
304
+
305
+ describe("type inference", () => {
306
+ it("validators without generics still infer base types", () => {
307
+ expectTypeOf(t.string()._type).toEqualTypeOf<string>();
308
+ expectTypeOf(t.int32()._type).toEqualTypeOf<number>();
309
+ expectTypeOf(t.bool()._type).toEqualTypeOf<boolean>();
310
+ expectTypeOf(t.int128()._type).toEqualTypeOf<bigint>();
311
+ expectTypeOf(t.uuid()._type).toEqualTypeOf<string>();
312
+ });
313
+
314
+ it("validators with generics infer the custom type", () => {
315
+ expectTypeOf(t.string<UserId>()._type).toEqualTypeOf<UserId>();
316
+ expectTypeOf(t.uuid<TraceId>()._type).toEqualTypeOf<TraceId>();
317
+ expectTypeOf(t.int32<Count>()._type).toEqualTypeOf<Count>();
318
+ expectTypeOf(t.bool<IsActive>()._type).toEqualTypeOf<IsActive>();
319
+ expectTypeOf(t.int128<BigId>()._type).toEqualTypeOf<BigId>();
320
+ expectTypeOf(t.dateTime<Timestamp>()._type).toEqualTypeOf<Timestamp>();
321
+ expectTypeOf(
322
+ t.dateTime<Timestamp>("UTC")._type,
323
+ ).toEqualTypeOf<Timestamp>();
324
+ expectTypeOf(
325
+ t.dateTime64<Timestamp>(3)._type,
326
+ ).toEqualTypeOf<Timestamp>();
327
+ expectTypeOf(t.decimal<Price>(10, 2)._type).toEqualTypeOf<Price>();
328
+ });
329
+
330
+ it("custom types flow through nullable", () => {
331
+ expectTypeOf(
332
+ t.string<UserId>().nullable()._type,
333
+ ).toEqualTypeOf<UserId | null>();
334
+ expectTypeOf(
335
+ t.int32<Count>().nullable()._type,
336
+ ).toEqualTypeOf<Count | null>();
337
+ });
338
+
339
+ it("custom types flow through lowCardinality", () => {
340
+ expectTypeOf(
341
+ t.string<UserId>().lowCardinality()._type,
342
+ ).toEqualTypeOf<UserId>();
343
+ });
344
+
345
+ it("custom types flow through InferRow", () => {
346
+ const ds = defineDatasource("test_custom_types", {
347
+ schema: {
348
+ user_id: t.string<UserId>(),
349
+ event_count: t.int32<Count>(),
350
+ created_at: t.dateTime<Timestamp>(),
351
+ name: t.string(),
352
+ },
353
+ engine: engine.mergeTree({ sortingKey: ["user_id"] }),
354
+ });
355
+
356
+ type Row = InferRow<typeof ds>;
357
+
358
+ expectTypeOf<Row["user_id"]>().toEqualTypeOf<UserId>();
359
+ expectTypeOf<Row["event_count"]>().toEqualTypeOf<Count>();
360
+ expectTypeOf<Row["created_at"]>().toEqualTypeOf<Timestamp>();
361
+ expectTypeOf<Row["name"]>().toEqualTypeOf<string>();
362
+ });
363
+
364
+ it("rejects generics that violate base type constraint", () => {
365
+ // @ts-expect-error - number does not extend string
366
+ t.string<number>();
367
+
368
+ // @ts-expect-error - string does not extend number
369
+ t.int32<string>();
370
+
371
+ // @ts-expect-error - string does not extend boolean
372
+ t.bool<string>();
373
+
374
+ // @ts-expect-error - number does not extend bigint
375
+ t.int128<number>();
376
+ });
377
+ });
378
+
379
+ describe("all validators accept custom generics", () => {
380
+ it("string-based validators", () => {
381
+ type S = string & { readonly __brand: "S" };
382
+ expectTypeOf(t.string<S>()._type).toEqualTypeOf<S>();
383
+ expectTypeOf(t.fixedString<S>(10)._type).toEqualTypeOf<S>();
384
+ expectTypeOf(t.uuid<S>()._type).toEqualTypeOf<S>();
385
+ expectTypeOf(t.ipv4<S>()._type).toEqualTypeOf<S>();
386
+ expectTypeOf(t.ipv6<S>()._type).toEqualTypeOf<S>();
387
+ expectTypeOf(t.date<S>()._type).toEqualTypeOf<S>();
388
+ expectTypeOf(t.date32<S>()._type).toEqualTypeOf<S>();
389
+ expectTypeOf(t.dateTime<S>()._type).toEqualTypeOf<S>();
390
+ expectTypeOf(t.dateTime<S>("UTC")._type).toEqualTypeOf<S>();
391
+ expectTypeOf(t.dateTime64<S>()._type).toEqualTypeOf<S>();
392
+ expectTypeOf(t.dateTime64<S>(6, "UTC")._type).toEqualTypeOf<S>();
393
+ });
394
+
395
+ it("number-based validators", () => {
396
+ type N = number & { readonly __brand: "N" };
397
+ expectTypeOf(t.int8<N>()._type).toEqualTypeOf<N>();
398
+ expectTypeOf(t.int16<N>()._type).toEqualTypeOf<N>();
399
+ expectTypeOf(t.int32<N>()._type).toEqualTypeOf<N>();
400
+ expectTypeOf(t.int64<N>()._type).toEqualTypeOf<N>();
401
+ expectTypeOf(t.uint8<N>()._type).toEqualTypeOf<N>();
402
+ expectTypeOf(t.uint16<N>()._type).toEqualTypeOf<N>();
403
+ expectTypeOf(t.uint32<N>()._type).toEqualTypeOf<N>();
404
+ expectTypeOf(t.uint64<N>()._type).toEqualTypeOf<N>();
405
+ expectTypeOf(t.float32<N>()._type).toEqualTypeOf<N>();
406
+ expectTypeOf(t.float64<N>()._type).toEqualTypeOf<N>();
407
+ expectTypeOf(t.decimal<N>(10, 2)._type).toEqualTypeOf<N>();
408
+ });
409
+
410
+ it("bigint-based validators", () => {
411
+ type B = bigint & { readonly __brand: "B" };
412
+ expectTypeOf(t.int128<B>()._type).toEqualTypeOf<B>();
413
+ expectTypeOf(t.int256<B>()._type).toEqualTypeOf<B>();
414
+ expectTypeOf(t.uint128<B>()._type).toEqualTypeOf<B>();
415
+ expectTypeOf(t.uint256<B>()._type).toEqualTypeOf<B>();
416
+ });
417
+
418
+ it("boolean-based validators", () => {
419
+ type Bool = boolean & { readonly __brand: "Bool" };
420
+ expectTypeOf(t.bool<Bool>()._type).toEqualTypeOf<Bool>();
421
+ });
422
+ });
423
+ });
226
424
  });