Skip to content

Commit

Permalink
Fix Embedded TemplateLiteral Generation
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Jun 22, 2024
1 parent f065cfc commit b0f2ccf
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/type/template-literal/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type TFromTemplateLiteralUnionKinds<T extends TTemplateLiteralKind[]> =
type TFromTemplateLiteralKinds<T extends TTemplateLiteralKind[], Acc extends TLiteralValue[][] = []> =
T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]]
? (
L extends TTemplateLiteral<infer S extends TTemplateLiteralKind[]> ? TFromTemplateLiteralKinds<[...S, ...R], Acc> :
L extends TLiteral<infer S extends TLiteralValue> ? TFromTemplateLiteralKinds<R, [...Acc, [S]]> :
L extends TUnion<infer S extends TTemplateLiteralKind[]> ? TFromTemplateLiteralKinds<R, [...Acc, TFromTemplateLiteralUnionKinds<S>]> :
L extends TBoolean ? TFromTemplateLiteralKinds<R, [...Acc, ['true', 'false']]> :
Expand Down
37 changes: 36 additions & 1 deletion test/runtime/type/guard/type/template-literal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TypeGuard } from '@sinclair/typebox'
import { Type } from '@sinclair/typebox'
import { Type, TemplateLiteralGenerate } from '@sinclair/typebox'
import { Assert } from '../../../assert/index'

describe('guard/type/TTemplateLiteral', () => {
Expand Down Expand Up @@ -44,4 +44,39 @@ describe('guard/type/TTemplateLiteral', () => {
T.pattern = T.pattern.slice(0, T.pattern.length - 1)
Assert.IsFalse(TypeGuard.IsTemplateLiteral(T))
})
// ----------------------------------------------------------------
// issue: https://github.com/sinclairzx81/typebox/issues/913
// ----------------------------------------------------------------
it('Should generate embedded template literal 1', () => {
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])])
const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B])
const T = TemplateLiteralGenerate(L)
Assert.IsEqual(T, ['KEYAX', 'KEYAY', 'KEYBX', 'KEYBY'])
})
it('Should generate embedded template literal 2', () => {
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])])
const L = Type.TemplateLiteral([A, Type.Literal('KEY'), B])
const T = TemplateLiteralGenerate(L)
Assert.IsEqual(T, ['AKEYX', 'AKEYY', 'BKEYX', 'BKEYY'])
})
it('Should generate embedded template literal 3', () => {
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])])
const L = Type.TemplateLiteral([A, B, Type.Literal('KEY')])
const T = TemplateLiteralGenerate(L)
Assert.IsEqual(T, ['AXKEY', 'AYKEY', 'BXKEY', 'BYKEY'])
})
it('Should map embedded template literal', () => {
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])])
const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B])
const T = Type.Mapped(L, (K) => Type.Null())
Assert.IsTrue(TypeGuard.IsObject(T))
Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYAX))
Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYAY))
Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYBX))
Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYBY))
})
})
15 changes: 15 additions & 0 deletions test/static/template-literal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,18 @@ import { Type } from '@sinclair/typebox'
'$propAx}Yx' | '$propBx}Yx' | '$propCx}Yx'
>()
}
// ---------------------------------------------------------------------
// issue: https://github.com/sinclairzx81/typebox/issues/913
// ---------------------------------------------------------------------
{
const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])])
const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])])
const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B])
const T = Type.Mapped(L, (K) => Type.Null())
Expect(T).ToStatic<{
KEYAX: null
KEYAY: null
KEYBX: null
KEYBY: null
}>()
}

0 comments on commit b0f2ccf

Please sign in to comment.