# @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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://angular-ru.gitbook.io/sdk/cdk/typings.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
