Skip to content

Commit c9ad6ba

Browse files
authored
Version 1.1.12 (#1555)
* Intrinsic Length Property Indexer * ChangeLog * Version
1 parent 59600e6 commit c9ad6ba

6 files changed

Lines changed: 70 additions & 12 deletions

File tree

changelog/1.1.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
---
44

55
### Version Updates
6+
- [Revision 1.1.12](https://github.com/sinclairzx81/typebox/pull/1555)
7+
- Intrinsic Length Property Indexer for Tuple and Array types.
68
- [Revision 1.1.11](https://github.com/sinclairzx81/typebox/pull/1553)
79
- Linear Scan for Common Formats | 2020-12 Spec Alignment
810
- [Revision 1.1.10](https://github.com/sinclairzx81/typebox/pull/1552)

src/type/engine/indexed/from-array.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31+
import { Guard } from '../../../guard/index.ts'
3132
import { type TSchema } from '../../types/schema.ts'
3233
import { type TIntersect, Intersect, IsIntersect } from '../../types/intersect.ts'
3334
import { type TUnion, Union, IsUnion } from '../../types/union.ts'
@@ -83,12 +84,27 @@ export function NormalizeIndexer<Type extends TSchema>(type: Type): TNormalizeIn
8384
export type TFromArray<Type extends TSchema, Indexer extends TSchema,
8485
NormalizedIndexer extends TSchema = TNormalizeIndexer<Indexer>,
8586
Check extends ExtendsResult.TResult = TExtends<{}, NormalizedIndexer, TNumber>,
86-
Result extends TSchema = Check extends ExtendsResult.TExtendsTrueLike ? Type : TNever
87-
> = Result
87+
Result extends TSchema = (
88+
// indexer
89+
Check extends ExtendsResult.TExtendsTrueLike
90+
? Type
91+
// length (intrinsic)
92+
: Indexer extends TLiteral<infer _ extends 'length'>
93+
? TNumber
94+
: TNever
95+
)> = Result
8896
export function FromArray<Type extends TSchema, Indexer extends TSchema>(type: Type, indexer: Indexer): TFromArray<Type, Indexer> {
8997
const normalizedIndexer = NormalizeIndexer(indexer)
9098
const check = Extends({}, normalizedIndexer, Number())
91-
const result = ExtendsResult.IsExtendsTrueLike(check) ? type : Never()
99+
const result = (
100+
// indexer
101+
ExtendsResult.IsExtendsTrueLike(check)
102+
? type
103+
// length (intrinsic)
104+
: IsLiteral(indexer) && Guard.IsEqual(indexer.const, 'length')
105+
? Number()
106+
: Never()
107+
)
92108
return result as never
93109
}
94110

src/type/engine/indexed/from-tuple.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ THE SOFTWARE.
2828

2929
// deno-fmt-ignore-file
3030

31+
import { Guard } from '../../../guard/index.ts'
3132
import { type TSchema } from '../../types/schema.ts'
32-
import { type TLiteral, Literal } from '../../types/literal.ts'
33+
import { type TLiteral, Literal, IsLiteral } from '../../types/literal.ts'
3334
import { type TNumber, IsNumber } from '../../types/number.ts'
3435
import { type TInteger, IsInteger } from '../../types/integer.ts'
3536

@@ -80,16 +81,23 @@ function FromTupleWithoutIndexer<Types extends TSchema[]>(types: [...Types]): TF
8081
// ------------------------------------------------------------------
8182
export type TFromTuple<Types extends TSchema[], Indexer extends TSchema,
8283
Result extends TSchema = (
83-
Indexer extends TNumber | TInteger
84-
? TFromTupleWithoutIndexer<Types>
85-
: TFromTupleWithIndexer<Types, Indexer>
84+
// length (intrinsic)
85+
Indexer extends TLiteral<infer _ extends 'length'>
86+
? TLiteral<Types['length']>
87+
// indexer
88+
: Indexer extends TNumber | TInteger
89+
? TFromTupleWithoutIndexer<Types>
90+
: TFromTupleWithIndexer<Types, Indexer>
8691
)
8792
> = Result
8893
export function FromTuple<Types extends TSchema[], Indexer extends TSchema>(types: [...Types], indexer: Indexer): TFromTuple<Types, Indexer> {
89-
9094
return (
91-
IsNumber(indexer) || IsInteger(indexer)
92-
? FromTupleWithoutIndexer(types)
93-
: FromTupleWithIndexer(types, indexer)
95+
// length (intrinsic)
96+
IsLiteral(indexer) && Guard.IsEqual(indexer.const, 'length')
97+
? Literal(types.length)
98+
// indexer
99+
: IsNumber(indexer) || IsInteger(indexer)
100+
? FromTupleWithoutIndexer(types)
101+
: FromTupleWithIndexer(types, indexer)
94102
) as never
95103
}

tasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Range } from './task/range/index.ts'
88
import { Metrics } from './task/metrics/index.ts'
99
import { Task } from 'tasksmith'
1010

11-
const Version = '1.1.11'
11+
const Version = '1.1.12'
1212

1313
// ------------------------------------------------------------------
1414
// Build

test/typebox/runtime/type/engine/action/indexed.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,21 @@ Test('Should Index 35', () => {
471471
Assert.IsTrue(Type.IsNumber(K.anyOf[0]))
472472
Assert.IsTrue(Type.IsString(K.anyOf[1]))
473473
})
474+
// ------------------------------------------------------------------
475+
// Length
476+
// ------------------------------------------------------------------
477+
Test('Should Index 36', () => {
478+
const T = Type.Tuple([
479+
Type.Literal(1),
480+
Type.Literal(2),
481+
Type.Literal(3)
482+
])
483+
const S: Type.TLiteral<3> = Type.Index(T, Type.Literal('length'))
484+
Assert.IsTrue(Type.IsLiteral(S))
485+
Assert.IsEqual(S.const, 3)
486+
})
487+
Test('Should Index 37', () => {
488+
const T = Type.Array(Type.String())
489+
const S: Type.TNumber = Type.Index(T, Type.Literal('length'))
490+
Assert.IsTrue(Type.IsNumber(S))
491+
})

test/typebox/runtime/type/script/indexed.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,17 @@ Test('Should Indexed 10', () => {
6262
const T: Type.TNumber = Type.Instantiate({ A: Type.Script(`{ x: number }`) }, R)
6363
Assert.IsTrue(Type.IsNumber(T))
6464
})
65+
// ------------------------------------------------------------------
66+
// Length
67+
// ------------------------------------------------------------------
68+
Test('Should Indexed 11', () => {
69+
const T = Type.Script(`[1, 2, 3]`)
70+
const S: Type.TLiteral<3> = Type.Script({ T }, `T['length']`)
71+
Assert.IsTrue(Type.IsLiteral(S))
72+
Assert.IsEqual(S.const, 3)
73+
})
74+
Test('Should Indexed 12', () => {
75+
const T = Type.Script(`string[]`)
76+
const S: Type.TNumber = Type.Script({ T }, `T['length']`)
77+
Assert.IsTrue(Type.IsNumber(S))
78+
})

0 commit comments

Comments
 (0)