Skip to content

Commit

Permalink
feat(@angular-ru/common): item functions type (#684)
Browse files Browse the repository at this point in the history
* 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 <omaxphp@yandex.ru>
  • Loading branch information
Markiewic and splincode authored Jun 20, 2021
1 parent 7597ca4 commit 000b2fd
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 13 deletions.
6 changes: 3 additions & 3 deletions packages/common/array/src/take-first-item.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Nullable } from '@angular-ru/common/typings';
import { Nullable, TupleItem } from '@angular-ru/common/typings';

export function takeFirstItem<T>(array?: Nullable<T[]>): Nullable<T> {
return array?.[0];
export function takeFirstItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): TupleItem<ArrayType, 0> {
return (Array.isArray(array) ? array[0] : undefined) as TupleItem<ArrayType, 0>;
}
6 changes: 3 additions & 3 deletions packages/common/array/src/take-last-item.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Nullable } from '@angular-ru/common/typings';
import { LastOfTuple, Nullable } from '@angular-ru/common/typings';

export function takeLastItem<T>(array?: Nullable<T[]>): Nullable<T> {
return array?.[array?.length - 1];
export function takeLastItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): LastOfTuple<ArrayType> {
return (Array.isArray(array) ? array[array.length - 1] : undefined) as LastOfTuple<ArrayType>;
}
6 changes: 3 additions & 3 deletions packages/common/array/src/take-second-item.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Nullable } from '@angular-ru/common/typings';
import { Nullable, TupleItem } from '@angular-ru/common/typings';

export function takeSecondItem<T>(array?: Nullable<T[]>): Nullable<T> {
return array?.[1];
export function takeSecondItem<ArrayType extends Nullable<unknown[]>>(array: ArrayType): TupleItem<ArrayType, 1> {
return (Array.isArray(array) ? array[1] : undefined) as TupleItem<ArrayType, 1>;
}
12 changes: 8 additions & 4 deletions packages/common/array/src/take-third-item.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Nullable } from '@angular-ru/common/typings';
import { Nullable, TupleItem } from '@angular-ru/common/typings';

export function takeThirdItem<T>(array?: Nullable<T[]>): Nullable<T> {
const thirdItemIndex: number = 2;
return array?.[thirdItemIndex];
type ThirdItemIndex = 2;
const thirdItemIndex: ThirdItemIndex = 2;

export function takeThirdItem<ArrayType extends Nullable<unknown[]>>(
array: ArrayType
): TupleItem<ArrayType, ThirdItemIndex> {
return (Array.isArray(array) ? array[thirdItemIndex] : undefined) as TupleItem<ArrayType, ThirdItemIndex>;
}
40 changes: 40 additions & 0 deletions packages/common/docs/typings.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,43 @@ function makeSomeOperations(form: FormGroup, descriptor: DateIntervalDescriptor)
// ...
}
```

- `Tuple`

```ts
type NumberCouple = Tuple<number, 2>; // [number, number]
type Number4 = Tuple<number, 4>; // [number, number, number, number]
type BracedString = Tuple<string>; // [string]
type NumberCouple = Tuple<string, 0>; // []
```

- `InfiniteTuple`

```ts
type CoupleAndMaybeSomeNumbers = InfiniteTuple<number, 2>; // [number, number, ...number]
type AtLeast4Numbers = InfiniteTuple<number, 4>; // [number, number, number, number, ...number]
type AtLeastOneLine = InfiniteTuple<string>; // [string, ...string]
type SomeLines = InfiniteTuple<string, 0>; // string[]
```

- `LastOfTuple`

```ts
type Number = LastOfTuple<[number]>; // number
type MaybeString = LastOfTuple<string[]>; // string | undefined
type Boolean = LastOfTuple<[string, boolean]>; // boolean
type StringOrNumber = LastOfTuple<[string, ...number[]]>; // string | number
type Nothing = LastOfTuple<[]>; // undefined
```

- `TupleItem`

```ts
type Number = TupleItem<[number], 0>; // number
type MaybeString = TupleItem<string[], 1>; // string | undefined
type Boolean = TupleItem<[string, boolean], 1>; // boolean
type String = TupleItem<[string, ...number[]], 0>; // string
type MaybeNumber = TupleItem<[string, ...number[]], 3>; // number | undefined
type Nothing = TupleItem<[], 0>; // undefined
type NothingToo = TupleItem<[], 3>; // undefined
```
3 changes: 3 additions & 0 deletions packages/common/typings/src/infinite-tuple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Tuple } from './tuple';

export type InfiniteTuple<ItemType, Length extends number = 1> = [...Tuple<ItemType, Length>, ...ItemType[]];
7 changes: 7 additions & 0 deletions packages/common/typings/src/last-of-tuple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type LastOfTuple<ArrayType> = ArrayType extends unknown[]
? ArrayType extends []
? undefined
: ArrayType extends [unknown, ...unknown[]]
? ArrayType[ArrayType extends [unknown, ...infer Rest] ? Rest['length'] : number]
: ArrayType[number] | undefined
: undefined;
4 changes: 4 additions & 0 deletions packages/common/typings/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ export { Descriptor } from './descriptor';
export { EmptyValue } from './empty-value';
export { Fn } from './fn';
export { Immutable, Mutable, PrimitiveType } from './immutability';
export { InfiniteTuple } from './infinite-tuple';
export { InputBoolean } from './input-boolean';
export { Join } from './join';
export { KeyOfList } from './key-of-list';
export { KeyValueComparator } from './key-value-comparator';
export { KeyboardKeys } from './keyboard';
export { KeysOfType } from './keys-of-type';
export { LastOfTuple } from './last-of-tuple';
export { Leaves } from './leaves';
export { NgCssClasses } from './ng-css-classes';
export { Nullable } from './nullable';
Expand All @@ -30,3 +32,5 @@ export { Resolver } from './resolver';
export { SortOrderType } from './sort-order-type';
export { StringValuesOfEnum } from './string-values-of-enum';
export { Timestamp } from './timestamp';
export { Tuple } from './tuple';
export { TupleItem } from './tuple-item';
7 changes: 7 additions & 0 deletions packages/common/typings/src/tuple-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { InfiniteTuple } from './infinite-tuple';

export type TupleItem<ArrayType, Index extends number> = ArrayType extends unknown[]
? ArrayType extends [unknown, ...InfiniteTuple<unknown, Index>]
? ArrayType[Index]
: ArrayType[Index] | undefined
: undefined;
3 changes: 3 additions & 0 deletions packages/common/typings/src/tuple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type Tuple<ItemType, Length extends number = 1, Base extends unknown[] = []> = Base['length'] extends Length
? Base
: Tuple<ItemType, Length, [ItemType, ...Base]>;

0 comments on commit 000b2fd

Please sign in to comment.