From 000b2fdbf856202f55f19b33f40ff5466f92b407 Mon Sep 17 00:00:00 2001 From: Schirbak <33288503+Schirbak@users.noreply.github.com> Date: Sun, 20 Jun 2021 18:58:50 +0300 Subject: [PATCH] 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 --- packages/common/array/src/take-first-item.ts | 6 +-- packages/common/array/src/take-last-item.ts | 6 +-- packages/common/array/src/take-second-item.ts | 6 +-- packages/common/array/src/take-third-item.ts | 12 ++++-- packages/common/docs/typings.md | 40 +++++++++++++++++++ packages/common/typings/src/infinite-tuple.ts | 3 ++ packages/common/typings/src/last-of-tuple.ts | 7 ++++ packages/common/typings/src/public_api.ts | 4 ++ packages/common/typings/src/tuple-item.ts | 7 ++++ packages/common/typings/src/tuple.ts | 3 ++ 10 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 packages/common/typings/src/infinite-tuple.ts create mode 100644 packages/common/typings/src/last-of-tuple.ts create mode 100644 packages/common/typings/src/tuple-item.ts create mode 100644 packages/common/typings/src/tuple.ts diff --git a/packages/common/array/src/take-first-item.ts b/packages/common/array/src/take-first-item.ts index 883961612..52d10fcb1 100644 --- a/packages/common/array/src/take-first-item.ts +++ b/packages/common/array/src/take-first-item.ts @@ -1,5 +1,5 @@ -import { Nullable } from '@angular-ru/common/typings'; +import { Nullable, TupleItem } from '@angular-ru/common/typings'; -export function takeFirstItem(array?: Nullable): Nullable { - return array?.[0]; +export function takeFirstItem>(array: ArrayType): TupleItem { + return (Array.isArray(array) ? array[0] : undefined) as TupleItem; } diff --git a/packages/common/array/src/take-last-item.ts b/packages/common/array/src/take-last-item.ts index 7c48f7198..1deb8cb1c 100644 --- a/packages/common/array/src/take-last-item.ts +++ b/packages/common/array/src/take-last-item.ts @@ -1,5 +1,5 @@ -import { Nullable } from '@angular-ru/common/typings'; +import { LastOfTuple, Nullable } from '@angular-ru/common/typings'; -export function takeLastItem(array?: Nullable): Nullable { - return array?.[array?.length - 1]; +export function takeLastItem>(array: ArrayType): LastOfTuple { + return (Array.isArray(array) ? array[array.length - 1] : undefined) as LastOfTuple; } diff --git a/packages/common/array/src/take-second-item.ts b/packages/common/array/src/take-second-item.ts index 5acdb6ae6..c455850ff 100644 --- a/packages/common/array/src/take-second-item.ts +++ b/packages/common/array/src/take-second-item.ts @@ -1,5 +1,5 @@ -import { Nullable } from '@angular-ru/common/typings'; +import { Nullable, TupleItem } from '@angular-ru/common/typings'; -export function takeSecondItem(array?: Nullable): Nullable { - return array?.[1]; +export function takeSecondItem>(array: ArrayType): TupleItem { + return (Array.isArray(array) ? array[1] : undefined) as TupleItem; } diff --git a/packages/common/array/src/take-third-item.ts b/packages/common/array/src/take-third-item.ts index 35aa75b5e..200e48acc 100644 --- a/packages/common/array/src/take-third-item.ts +++ b/packages/common/array/src/take-third-item.ts @@ -1,6 +1,10 @@ -import { Nullable } from '@angular-ru/common/typings'; +import { Nullable, TupleItem } from '@angular-ru/common/typings'; -export function takeThirdItem(array?: Nullable): Nullable { - const thirdItemIndex: number = 2; - return array?.[thirdItemIndex]; +type ThirdItemIndex = 2; +const thirdItemIndex: ThirdItemIndex = 2; + +export function takeThirdItem>( + array: ArrayType +): TupleItem { + return (Array.isArray(array) ? array[thirdItemIndex] : undefined) as TupleItem; } diff --git a/packages/common/docs/typings.md b/packages/common/docs/typings.md index 1e6a3d6ed..78118c20f 100644 --- a/packages/common/docs/typings.md +++ b/packages/common/docs/typings.md @@ -190,3 +190,43 @@ function makeSomeOperations(form: FormGroup, descriptor: DateIntervalDescriptor) // ... } ``` + +- `Tuple` + +```ts +type NumberCouple = Tuple; // [number, number] +type Number4 = Tuple; // [number, number, number, number] +type BracedString = Tuple; // [string] +type NumberCouple = Tuple; // [] +``` + +- `InfiniteTuple` + +```ts +type CoupleAndMaybeSomeNumbers = InfiniteTuple; // [number, number, ...number] +type AtLeast4Numbers = InfiniteTuple; // [number, number, number, number, ...number] +type AtLeastOneLine = InfiniteTuple; // [string, ...string] +type SomeLines = InfiniteTuple; // string[] +``` + +- `LastOfTuple` + +```ts +type Number = LastOfTuple<[number]>; // number +type MaybeString = LastOfTuple; // 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 | 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 +``` diff --git a/packages/common/typings/src/infinite-tuple.ts b/packages/common/typings/src/infinite-tuple.ts new file mode 100644 index 000000000..4dffa76c2 --- /dev/null +++ b/packages/common/typings/src/infinite-tuple.ts @@ -0,0 +1,3 @@ +import { Tuple } from './tuple'; + +export type InfiniteTuple = [...Tuple, ...ItemType[]]; diff --git a/packages/common/typings/src/last-of-tuple.ts b/packages/common/typings/src/last-of-tuple.ts new file mode 100644 index 000000000..2ed0b5b34 --- /dev/null +++ b/packages/common/typings/src/last-of-tuple.ts @@ -0,0 +1,7 @@ +export type LastOfTuple = ArrayType extends unknown[] + ? ArrayType extends [] + ? undefined + : ArrayType extends [unknown, ...unknown[]] + ? ArrayType[ArrayType extends [unknown, ...infer Rest] ? Rest['length'] : number] + : ArrayType[number] | undefined + : undefined; diff --git a/packages/common/typings/src/public_api.ts b/packages/common/typings/src/public_api.ts index 0e8c122ba..380642feb 100644 --- a/packages/common/typings/src/public_api.ts +++ b/packages/common/typings/src/public_api.ts @@ -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'; @@ -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'; diff --git a/packages/common/typings/src/tuple-item.ts b/packages/common/typings/src/tuple-item.ts new file mode 100644 index 000000000..5b0cf5092 --- /dev/null +++ b/packages/common/typings/src/tuple-item.ts @@ -0,0 +1,7 @@ +import { InfiniteTuple } from './infinite-tuple'; + +export type TupleItem = ArrayType extends unknown[] + ? ArrayType extends [unknown, ...InfiniteTuple] + ? ArrayType[Index] + : ArrayType[Index] | undefined + : undefined; diff --git a/packages/common/typings/src/tuple.ts b/packages/common/typings/src/tuple.ts new file mode 100644 index 000000000..dec1a02e0 --- /dev/null +++ b/packages/common/typings/src/tuple.ts @@ -0,0 +1,3 @@ +export type Tuple = Base['length'] extends Length + ? Base + : Tuple;