Skip to content

Commit 3a54365

Browse files
authored
Intrinsic String Mapping (#517)
1 parent 72ffd1a commit 3a54365

12 files changed

+60
-5
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sinclair/typebox",
3-
"version": "0.30.1",
3+
"version": "0.30.2",
44
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
55
"keywords": [
66
"typescript",

src/typebox.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ export type TIntrinsicLiteral<T, M extends TIntrinsicMode> =
434434
M extends 'Uppercase' ? Uppercase<T> :
435435
M extends 'Lowercase' ? Lowercase<T> :
436436
string
437-
: ''
437+
: T
438438
// prettier-ignore
439439
export type TIntrinsicRest<T extends TSchema[], M extends TIntrinsicMode> = T extends [infer L, ...infer R]
440440
? [TIntrinsic<AssertType<L>, M>, ...TIntrinsicRest<AssertRest<R>, M>]
@@ -2176,7 +2176,7 @@ export namespace Intrinsic {
21762176
mode === 'Capitalize' ? Capitalize(value) :
21772177
mode === 'Uppercase' ? Uppercase(value) :
21782178
mode === 'Lowercase' ? Lowercase(value) :
2179-
value) : ''
2179+
value) : value.toString()
21802180
}
21812181
function IntrinsicRest(schema: TSchema[], mode: TIntrinsicMode): TSchema[] {
21822182
if (schema.length === 0) return []

test/runtime/type/guard/capitalize.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ describe('type/guard/Capitalize', () => {
2525
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
2626
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
2727
})
28+
it('Should guard for Capitalize 5', () => {
29+
const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
30+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
31+
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
32+
})
2833
})

test/runtime/type/guard/lowercase.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ describe('type/guard/Lowercase', () => {
2525
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
2626
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
2727
})
28+
it('Should guard for Lowercase 5', () => {
29+
const T = Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
30+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
31+
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
32+
})
2833
})

test/runtime/type/guard/uncapitalize.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ describe('type/guard/Uncapitalize', () => {
2525
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
2626
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
2727
})
28+
it('Should guard for Uncapitalize 5', () => {
29+
const T = Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
30+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
31+
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
32+
})
2833
})

test/runtime/type/guard/uppercase.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ describe('type/guard/Uppercase', () => {
2525
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
2626
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
2727
})
28+
it('Should guard for Uppercase 5', () => {
29+
const T = Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
30+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
31+
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
32+
})
2833
})

test/runtime/type/intrinsic/intrinsic.ts

+23
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,29 @@ describe('type/intrinsic/IntrinsicString', () => {
110110
Assert.IsEqual(T.pattern, '^(hello1world|hello2world)$')
111111
})
112112
// ----------------------------------------------------
113+
// Mode: TemplateLiteral Numeric
114+
// ----------------------------------------------------
115+
it('Should map template literal numeric: Capitalize', () => {
116+
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Capitalize')
117+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
118+
Assert.IsEqual(T.pattern, '^(Hello1|Hello2)$')
119+
})
120+
it('Should map template literal numeric: Uncapitalize', () => {
121+
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uncapitalize')
122+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
123+
Assert.IsEqual(T.pattern, '^(hELLO1|hELLO2)$')
124+
})
125+
it('Should map template literal numeric: Uppercase', () => {
126+
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uppercase')
127+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
128+
Assert.IsEqual(T.pattern, '^(HELLO1|HELLO2)$')
129+
})
130+
it('Should map template literal numeric: Lowercase', () => {
131+
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Lowercase')
132+
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
133+
Assert.IsEqual(T.pattern, '^(hello1|hello2)$')
134+
})
135+
// ----------------------------------------------------
113136
// Mode: TemplateLiteral Patterns
114137
// ----------------------------------------------------
115138
it('Should map template literal patterns 1', () => {

test/static/capitalize.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ Expect(Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')]
77

88
Expect(Type.Capitalize(Type.TemplateLiteral('hello${0|1}'))).ToInfer<'Hello0' | 'Hello1'>()
99

10+
// prettier-ignore
11+
Expect(Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'Hello1' | 'Hello2'>()
12+
1013
// passthrough
1114
Expect(Type.Capitalize(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()

test/static/lowercase.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ Expect(Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])
77

88
Expect(Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'hello0' | 'hello1'>()
99

10+
// prettier-ignore
11+
Expect(Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'hello1' | 'hello2'>()
12+
1013
// passthrough
1114
Expect(Type.Lowercase(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()

test/static/uncapitalize.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ Expect(Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD'
77

88
Expect(Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'hELLO0' | 'hELLO1'>()
99

10+
// prettier-ignore
11+
Expect(Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'hELLO1' | 'hELLO2'>()
12+
1013
// passthrough
1114
Expect(Type.Uncapitalize(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()

test/static/uppercase.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ Expect(Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')])
77

88
Expect(Type.Uppercase(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'HELLO0' | 'HELLO1'>()
99

10+
// prettier-ignore
11+
Expect(Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'HELLO1' | 'HELLO2'>()
12+
1013
// passthrough
1114
Expect(Type.Uppercase(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()

0 commit comments

Comments
 (0)