Skip to content

Commit 000b2fd

Browse files
Markiewicsplincode
andauthored
feat(@angular-ru/common): item functions type (#684)
* feat(@angular-ru/common): item functions type * fixup! feat(@angular-ru/common): item functions type * fixup! feat(@angular-ru/common): item functions type Co-authored-by: Max Ivanov <[email protected]>
1 parent 7597ca4 commit 000b2fd

10 files changed

+81
-13
lines changed

Diff for: packages/common/array/src/take-first-item.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Nullable } from '@angular-ru/common/typings';
1+
import { Nullable, TupleItem } from '@angular-ru/common/typings';
22

3-
export function takeFirstItem<T>(array?: Nullable<T[]>): Nullable<T> {
4-
return array?.[0];
3+
export function takeFirstItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): TupleItem<ArrayType, 0> {
4+
return (Array.isArray(array) ? array[0] : undefined) as TupleItem<ArrayType, 0>;
55
}

Diff for: packages/common/array/src/take-last-item.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Nullable } from '@angular-ru/common/typings';
1+
import { LastOfTuple, Nullable } from '@angular-ru/common/typings';
22

3-
export function takeLastItem<T>(array?: Nullable<T[]>): Nullable<T> {
4-
return array?.[array?.length - 1];
3+
export function takeLastItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): LastOfTuple<ArrayType> {
4+
return (Array.isArray(array) ? array[array.length - 1] : undefined) as LastOfTuple<ArrayType>;
55
}

Diff for: packages/common/array/src/take-second-item.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Nullable } from '@angular-ru/common/typings';
1+
import { Nullable, TupleItem } from '@angular-ru/common/typings';
22

3-
export function takeSecondItem<T>(array?: Nullable<T[]>): Nullable<T> {
4-
return array?.[1];
3+
export function takeSecondItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): TupleItem<ArrayType, 1> {
4+
return (Array.isArray(array) ? array[1] : undefined) as TupleItem<ArrayType, 1>;
55
}

Diff for: packages/common/array/src/take-third-item.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { Nullable } from '@angular-ru/common/typings';
1+
import { Nullable, TupleItem } from '@angular-ru/common/typings';
22

3-
export function takeThirdItem<T>(array?: Nullable<T[]>): Nullable<T> {
4-
const thirdItemIndex: number = 2;
5-
return array?.[thirdItemIndex];
3+
type ThirdItemIndex = 2;
4+
const thirdItemIndex: ThirdItemIndex = 2;
5+
6+
export function takeThirdItem<ArrayType extends Nullable<unknown[]>>(
7+
array: ArrayType
8+
): TupleItem<ArrayType, ThirdItemIndex> {
9+
return (Array.isArray(array) ? array[thirdItemIndex] : undefined) as TupleItem<ArrayType, ThirdItemIndex>;
610
}

Diff for: packages/common/docs/typings.md

+40
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,43 @@ function makeSomeOperations(form: FormGroup, descriptor: DateIntervalDescriptor)
190190
// ...
191191
}
192192
```
193+
194+
- `Tuple`
195+
196+
```ts
197+
type NumberCouple = Tuple<number, 2>; // [number, number]
198+
type Number4 = Tuple<number, 4>; // [number, number, number, number]
199+
type BracedString = Tuple<string>; // [string]
200+
type NumberCouple = Tuple<string, 0>; // []
201+
```
202+
203+
- `InfiniteTuple`
204+
205+
```ts
206+
type CoupleAndMaybeSomeNumbers = InfiniteTuple<number, 2>; // [number, number, ...number]
207+
type AtLeast4Numbers = InfiniteTuple<number, 4>; // [number, number, number, number, ...number]
208+
type AtLeastOneLine = InfiniteTuple<string>; // [string, ...string]
209+
type SomeLines = InfiniteTuple<string, 0>; // string[]
210+
```
211+
212+
- `LastOfTuple`
213+
214+
```ts
215+
type Number = LastOfTuple<[number]>; // number
216+
type MaybeString = LastOfTuple<string[]>; // string | undefined
217+
type Boolean = LastOfTuple<[string, boolean]>; // boolean
218+
type StringOrNumber = LastOfTuple<[string, ...number[]]>; // string | number
219+
type Nothing = LastOfTuple<[]>; // undefined
220+
```
221+
222+
- `TupleItem`
223+
224+
```ts
225+
type Number = TupleItem<[number], 0>; // number
226+
type MaybeString = TupleItem<string[], 1>; // string | undefined
227+
type Boolean = TupleItem<[string, boolean], 1>; // boolean
228+
type String = TupleItem<[string, ...number[]], 0>; // string
229+
type MaybeNumber = TupleItem<[string, ...number[]], 3>; // number | undefined
230+
type Nothing = TupleItem<[], 0>; // undefined
231+
type NothingToo = TupleItem<[], 3>; // undefined
232+
```

Diff for: packages/common/typings/src/infinite-tuple.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Tuple } from './tuple';
2+
3+
export type InfiniteTuple<ItemType, Length extends number = 1> = [...Tuple<ItemType, Length>, ...ItemType[]];

Diff for: packages/common/typings/src/last-of-tuple.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export type LastOfTuple<ArrayType> = ArrayType extends unknown[]
2+
? ArrayType extends []
3+
? undefined
4+
: ArrayType extends [unknown, ...unknown[]]
5+
? ArrayType[ArrayType extends [unknown, ...infer Rest] ? Rest['length'] : number]
6+
: ArrayType[number] | undefined
7+
: undefined;

Diff for: packages/common/typings/src/public_api.ts

+4
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ export { Descriptor } from './descriptor';
1313
export { EmptyValue } from './empty-value';
1414
export { Fn } from './fn';
1515
export { Immutable, Mutable, PrimitiveType } from './immutability';
16+
export { InfiniteTuple } from './infinite-tuple';
1617
export { InputBoolean } from './input-boolean';
1718
export { Join } from './join';
1819
export { KeyOfList } from './key-of-list';
1920
export { KeyValueComparator } from './key-value-comparator';
2021
export { KeyboardKeys } from './keyboard';
2122
export { KeysOfType } from './keys-of-type';
23+
export { LastOfTuple } from './last-of-tuple';
2224
export { Leaves } from './leaves';
2325
export { NgCssClasses } from './ng-css-classes';
2426
export { Nullable } from './nullable';
@@ -30,3 +32,5 @@ export { Resolver } from './resolver';
3032
export { SortOrderType } from './sort-order-type';
3133
export { StringValuesOfEnum } from './string-values-of-enum';
3234
export { Timestamp } from './timestamp';
35+
export { Tuple } from './tuple';
36+
export { TupleItem } from './tuple-item';

Diff for: packages/common/typings/src/tuple-item.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { InfiniteTuple } from './infinite-tuple';
2+
3+
export type TupleItem<ArrayType, Index extends number> = ArrayType extends unknown[]
4+
? ArrayType extends [unknown, ...InfiniteTuple<unknown, Index>]
5+
? ArrayType[Index]
6+
: ArrayType[Index] | undefined
7+
: undefined;

Diff for: packages/common/typings/src/tuple.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type Tuple<ItemType, Length extends number = 1, Base extends unknown[] = []> = Base['length'] extends Length
2+
? Base
3+
: Tuple<ItemType, Length, [ItemType, ...Base]>;

0 commit comments

Comments
 (0)