#### `@angular-ru/cdk/typings`

- `Nullable`

```typescript
@Component({})
class MyComponent {
  @Input() public list: Nullable<string[]>; // equals ~ @Input() public list: string[] | null | undefined;
}
```

- `Timestamp` - alias for timestamp type.

```typescript
let time: Timestamp = new Date().toISOString();
// or
time = new Date().getTime();
```

- `NonEmptyArray`

```typescript
import {NonEmptyArray} from '@angular-ru/cdk/typings';

export function assertIsEmptyList(arr: string[]): asserts arr is NonEmptyArray<string> {
  if (!Array.isArray(arr) || arr.length === 0) {
    throw new EmptyArrayList();
  }
}
```

- `PlainObject`, `PlainObjectOf<T>`

```typescript
const a: PlainObject = {a: 1, b: '2'};
const b: PlainObjectOf<number> = {a: 1, b: 2};
```

- `Fn<T, U>`

```typescript
const fn1: Fn = () => {};
const fn2: Fn = function (val: string) {};
```

- `DeepPartial<T>`

```typescript
const myWindow: DeepPartial<Window> = {};
console.log(myWindow?.navigator?.userAgent);
```

- `PrimaryKey`

```typescript
const idKey: string = PrimaryKey.ID;
```

- `Immutable<T>, Mutable<T>`

```typescript
const obj: Immutable<PlainObject> = {};
obj['a'] = 5; // TS: Index signature in type 'Immutable<PlainObject>' only permits reading
```

- `ClassType`

```typescript
function inject(typeRef: ClassType) {}

class A {}

inject(A);
```

- `KeyValueComparator`

```typescript
@Component({
  template: `
    <ng-container *ngFor="let item of data | keyvalue: compare"></ng-container>
  `,
})
export class MyComponent {
  public compare: KeyValueComparator = compareKeys;
  // ..
}
```

- `Couple<T>`

```typescript
let operands: Couple<number> = [1, 2];
let number: Couple<number> = [1];
//                           ~~~
let numbers: Couple<number> = [1, 2, 3];
//                            ~~~~~~~~~
```

- `KeyOfList<T>`

```typescript
class B {
  c: string = '';
}

class A {
  a: string = '';
  b: B = new B();
}

const keys: KeyOfList<A> = ['a', 'b']; // output keys
```

- `DeepKeyOfList<T>`

```typescript
class B {
  c: string = '';
  etc: {f: string} = {f: ''};
}

class A {
  a: string = '';
  b: B = new B();
}

const keys: DeepKeyOfList<A> = ['a', 'b.c', 'b.etc.f']; // output keys
```

- `Leaves<T>`

`Leaves<T>[] === DeepKeyOfList<T>`

- `Paths<T>`

```typescript
class B {
  c: string = '';
  etc: {f: string} = {f: ''};
}

class A {
  a: string = '';
  b: B = new B();
}

const paths: Paths<A>[] = ['a', 'b', 'b.c', 'b.etc', 'b.etc.f']; // output keys
```

also, you can:

```typescript
const etc: Paths<A['b']['etc']> = 'f';
```

- `KeysOfType<T, Type>`

```typescript
interface SomeInterface {
  someNumber: number;
  someString: string;
  someStringArray: string[];
  someAnotherNumber: number;
}

type SomeStringNumberKeys = KeysOfType<SomeInterface, string | number>;
// SomeStringNumberKeys === 'someNumber' | 'someString' | 'someAnotherNumber'
```

- `NgCssClasses`

```typescript
const myClasses: NgCssClasses = {'block__element--modificator': true};
```

- `DateIntervalDescriptor`

```typescript
const descriptor: DateIntervalDescriptor = {dateFromKey: 'dateFrom', dateToKey: 'dateTo'};
const updatedDate = makeSomeOperations(dateFormGroup, descriptor);

function makeSomeOperations(form: FormGroup, descriptor: DateIntervalDescriptor) {
  const fromControl: FormControl = form.get(descriptor.dateFromKey) as FormControl;
  const toControl: FormControl = form.get(descriptor.dateFromKey) as FormControl;
  // ...
}
```

- `Tuple`

```typescript
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`

```typescript
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`

```typescript
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`

```typescript
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
```
