Skip to content

Commit 8cbe46a

Browse files
committed
feat(nominal-inputs): add SizedStringInput type
Signed-off-by: Andres Correa Casablanca <andreu@kindspells.dev>
1 parent 899aee9 commit 8cbe46a

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

@coderspirit/nominal-inputs/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,24 @@ function onlyAcceptsIntegers<N extends number>(n: IntegerInput<N>): number {
3939
}
4040

4141
// Using the function
42-
onlyAcceptsIntegers(42) // All good :D
42+
onlyAcceptsIntegers(42) // All good :D
4343
onlyAcceptsIntegers(0.5) // Type Error!
4444
```
4545

46+
### `SizedStringInput<S>`
47+
48+
```typescript
49+
import type { SizedStringInput } from '@coderspirit/nominal-inputs'
50+
51+
function onlyAcceptsThreeCharStrings<S extends string>(s: SizedStringInput<S, 3>): void {
52+
console.log(s)
53+
}
54+
55+
onlyAcceptsThreeCharStrings("abc") // All good :D
56+
onlyAcceptsThreeCharStrings("ab") // Type Error!
57+
onlyAcceptsThreeCharStrings("abcd") // Type Error!
58+
```
59+
4660
### Other Input types
4761

4862
- `NegativeInput<N>`

@coderspirit/nominal-inputs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@coderspirit/nominal-inputs",
3-
"version": "1.1.4",
3+
"version": "1.2.0",
44
"description": "Extension of @coderspirit/nominal with 'input' types",
55
"main": "./dist/main.cjs",
66
"module": "./dist/main.mjs",

@coderspirit/nominal-inputs/src/main.mts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { FastProperty } from '@coderspirit/nominal'
22

3+
import type { StringLength } from './str.mts'
4+
35
// Basic Types (copied from Type-Fest)
46
// -----------------------------------------------------------------------------
57
type Numeric = number | bigint
@@ -85,3 +87,8 @@ export type PositiveIntegerInput<N extends Numeric = number> =
8587

8688
export type NegativeIntegerInput<N extends Numeric = number> =
8789
NegativeInput<N> & IntegerInput<N>
90+
91+
export type SizedStringInput<
92+
T extends string,
93+
N extends number,
94+
> = StringLength<T> extends N ? T : never
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copied from https://gist.github.com/sno2/7dac868ec6d11abb75250ce5e2b36041
3+
* @author Carter Snook <cartersnook04@gmail.com> github.com/sno2
4+
* @license https://unlicense.org/
5+
*/
6+
7+
type TCache = [string, 0[]]
8+
9+
type StringLengthUp<
10+
T extends string,
11+
$Acc extends 0[] = [],
12+
$Cache extends TCache[] = [[`$${string}`, [0]]],
13+
> = $Cache extends [
14+
infer C extends TCache,
15+
...infer $RestCache extends TCache[],
16+
]
17+
? (
18+
`${C[0]}${C[0]}_` extends `$${string}$${infer $After}`
19+
? `${C[0]}${$After}` extends `${infer $Before}_`
20+
? $Before
21+
: never
22+
: never
23+
) extends infer $DoubleC extends string
24+
? `$${T}` extends `${$DoubleC}${infer $Rest}`
25+
? StringLengthUp<
26+
$Rest,
27+
[...$Acc, ...C[1], ...C[1]],
28+
[[$DoubleC, [...C[1], ...C[1]]], ...$Cache]
29+
>
30+
: `$${T}` extends `${C[0]}${infer $Rest}`
31+
? StringLengthUp<$Rest, [...$Acc, ...C[1]], $Cache>
32+
: StringLengthDown<T, $Acc, $RestCache>
33+
: never
34+
: $Acc['length']
35+
36+
type StringLengthDown<
37+
T extends string,
38+
$Acc extends 0[],
39+
$Cache extends TCache[],
40+
> = $Cache extends [
41+
infer C extends TCache,
42+
...infer $RestCache extends TCache[],
43+
]
44+
? `$${T}` extends `${C[0]}${infer $Rest}`
45+
? StringLengthDown<$Rest, [...$Acc, ...C[1]], $Cache>
46+
: StringLengthDown<T, $Acc, $RestCache>
47+
: $Acc['length']
48+
49+
export type StringLength<S extends string> = S extends ''
50+
? 0
51+
: string extends S
52+
? number
53+
: number extends S['length']
54+
? StringLengthUp<S>
55+
: S['length']

0 commit comments

Comments
 (0)