Intrinsic String Mapping (#517)

This commit is contained in:
sinclairzx81
2023-08-02 19:59:39 +09:00
committed by GitHub
parent 72ffd1abca
commit 3a543656d6
12 changed files with 60 additions and 5 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@sinclair/typebox",
"version": "0.30.1",
"version": "0.30.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@sinclair/typebox",
"version": "0.30.1",
"version": "0.30.2",
"license": "MIT",
"devDependencies": {
"@sinclair/hammer": "^0.17.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.30.1",
"version": "0.30.2",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
+2 -2
View File
@@ -434,7 +434,7 @@ export type TIntrinsicLiteral<T, M extends TIntrinsicMode> =
M extends 'Uppercase' ? Uppercase<T> :
M extends 'Lowercase' ? Lowercase<T> :
string
: ''
: T
// prettier-ignore
export type TIntrinsicRest<T extends TSchema[], M extends TIntrinsicMode> = T extends [infer L, ...infer R]
? [TIntrinsic<AssertType<L>, M>, ...TIntrinsicRest<AssertRest<R>, M>]
@@ -2176,7 +2176,7 @@ export namespace Intrinsic {
mode === 'Capitalize' ? Capitalize(value) :
mode === 'Uppercase' ? Uppercase(value) :
mode === 'Lowercase' ? Lowercase(value) :
value) : ''
value) : value.toString()
}
function IntrinsicRest(schema: TSchema[], mode: TIntrinsicMode): TSchema[] {
if (schema.length === 0) return []
+5
View File
@@ -25,4 +25,9 @@ describe('type/guard/Capitalize', () => {
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
})
it('Should guard for Capitalize 5', () => {
const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$')
})
})
+5
View File
@@ -25,4 +25,9 @@ describe('type/guard/Lowercase', () => {
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
})
it('Should guard for Lowercase 5', () => {
const T = Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hello0|hello1)$')
})
})
+5
View File
@@ -25,4 +25,9 @@ describe('type/guard/Uncapitalize', () => {
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
})
it('Should guard for Uncapitalize 5', () => {
const T = Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$')
})
})
+5
View File
@@ -25,4 +25,9 @@ describe('type/guard/Uppercase', () => {
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
})
it('Should guard for Uppercase 5', () => {
const T = Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])]))
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$')
})
})
+23
View File
@@ -110,6 +110,29 @@ describe('type/intrinsic/IntrinsicString', () => {
Assert.IsEqual(T.pattern, '^(hello1world|hello2world)$')
})
// ----------------------------------------------------
// Mode: TemplateLiteral Numeric
// ----------------------------------------------------
it('Should map template literal numeric: Capitalize', () => {
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Capitalize')
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(Hello1|Hello2)$')
})
it('Should map template literal numeric: Uncapitalize', () => {
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uncapitalize')
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hELLO1|hELLO2)$')
})
it('Should map template literal numeric: Uppercase', () => {
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uppercase')
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(HELLO1|HELLO2)$')
})
it('Should map template literal numeric: Lowercase', () => {
const T = Intrinsic.Map(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Lowercase')
Assert.IsTrue(TypeGuard.TTemplateLiteral(T))
Assert.IsEqual(T.pattern, '^(hello1|hello2)$')
})
// ----------------------------------------------------
// Mode: TemplateLiteral Patterns
// ----------------------------------------------------
it('Should map template literal patterns 1', () => {
+3
View File
@@ -7,5 +7,8 @@ Expect(Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')]
Expect(Type.Capitalize(Type.TemplateLiteral('hello${0|1}'))).ToInfer<'Hello0' | 'Hello1'>()
// prettier-ignore
Expect(Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'Hello1' | 'Hello2'>()
// passthrough
Expect(Type.Capitalize(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()
+3
View File
@@ -7,5 +7,8 @@ Expect(Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])
Expect(Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'hello0' | 'hello1'>()
// prettier-ignore
Expect(Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'hello1' | 'hello2'>()
// passthrough
Expect(Type.Lowercase(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()
+3
View File
@@ -7,5 +7,8 @@ Expect(Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD'
Expect(Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'hELLO0' | 'hELLO1'>()
// prettier-ignore
Expect(Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'hELLO1' | 'hELLO2'>()
// passthrough
Expect(Type.Uncapitalize(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()
+3
View File
@@ -7,5 +7,8 @@ Expect(Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')])
Expect(Type.Uppercase(Type.TemplateLiteral('HELLO${0|1}'))).ToInfer<'HELLO0' | 'HELLO1'>()
// prettier-ignore
Expect(Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToBe<'HELLO1' | 'HELLO2'>()
// passthrough
Expect(Type.Uppercase(Type.Object({ x: Type.Number() }))).ToInfer<{ x: number }>()