-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(array): expose ArrayWith type declaration
- Loading branch information
1 parent
795cffa
commit 7855ac5
Showing
2 changed files
with
59 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { given, then, when } from 'test-fns'; | ||
|
||
describe('ArrayWith', () => { | ||
given('desire for array with min length', () => { | ||
then('we can declare the type', () => { | ||
let products: ArrayWith<'min', 1, string>; | ||
}); | ||
then('it allows arrays of exactly the min length to it', () => { | ||
const products: ArrayWith<'min', 1, string> = ['doughnut']; // 🍩 | ||
}); | ||
then('it allows arrays with more than the min length to it', () => { | ||
const products: ArrayWith<'min', 1, string> = ['doughnut', 'waffle']; // 🍩, 🧇 | ||
}); | ||
then('it blocks arrays with less than the min length to it', () => { | ||
// @ts-expect-error; Type '[]' is not assignable to type '[string, ...string[]]'. Source has 0 element(s) but target requires 1.ts(2322) | ||
const products: ArrayWith<'min', 1, string> = []; // 🍩, 🧇 | ||
}); | ||
}); | ||
given('desire for array with exact length', () => { | ||
then('we can declare the type', () => { | ||
let products: ArrayWith<'len', 1, string>; | ||
}); | ||
then('it allows arrays of exactly the desired length to it', () => { | ||
const products: ArrayWith<'len', 1, string> = ['doughnut']; // 🍩 | ||
}); | ||
then('it allows arrays with more than the desired length to it', () => { | ||
// @ts-expect-error; Type '[string, string]' is not assignable to type '[string]'.Source has 2 element(s) but target allows only 1. | ||
const products: ArrayWith<'len', 1, string> = ['doughnut', 'waffle']; // 🍩, 🧇 | ||
}); | ||
then('it blocks arrays with less than the desired length to it', () => { | ||
// @ts-expect-error; Type '[]' is not assignable to type '[string]'. Source has 0 element(s) but target requires 1.ts(2322) | ||
const products: ArrayWith<'len', 1, string> = []; | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* ref: | ||
* - https://stackoverflow.com/a/67655609/3068233 | ||
* - https://stackoverflow.com/a/73409753/3068233 | ||
*/ | ||
type BuildArrayWith< | ||
TCheck extends 'len' | 'min', // todo: support 'max' too? | ||
TLength extends number, | ||
TType, | ||
TCurrent extends TType[], | ||
> = TCurrent['length'] extends TLength | ||
? TCheck extends 'len' | ||
? [...TCurrent] | ||
: [...TCurrent, ...TType[]] | ||
: BuildArrayWith<TCheck, TLength, TType, [...TCurrent, TType]>; | ||
|
||
/** | ||
* declares a type of array with a check on its length | ||
*/ | ||
type ArrayWith< | ||
TCheck extends 'len' | 'min', // todo: support 'max' too? | ||
TLength extends number, | ||
TType, | ||
> = BuildArrayWith<TCheck, TLength, TType, []>; |