Examples of **correct** code for the `{ "allowAliases": "in-intersections" }` option:

```ts
// primitives
type Foo = string & string[];

type Foo = `a-${number}` & `b-${number}`;

// reference types
interface Bar {}
class Baz implements Bar {}

type Foo = Bar & Baz;
```

Examples of **incorrect** code for the `{ "allowAliases": "in-unions-and-intersections" }` option:

```ts
// primitives
type Foo = 'a';

type Foo = string;

type Foo = `foo-${number}`;

// reference types
interface Bar {}
class Baz implements Bar {}

type Foo = Bar;
```

Examples of **correct** code for the `{ "allowAliases": "in-unions-and-intersections" }` option:

```ts
// primitives
type Foo = 'a' | 'b';

type Foo = string | string[];

type Foo = string & string[];

type Foo = `a-${number}` & `b-${number}`;

type Foo = `a-${number}` | `b-${number}`;

// reference types
interface Bar {}
class Baz implements Bar {}

type Foo = Bar | Baz;

type Foo = Bar & Baz;
```

### `allowCallbacks`

This applies to function types.

The setting accepts the following values:

- `"always"` or `"never"` to active or deactivate the feature.

Examples of **correct** code for the `{ "allowCallbacks": "always" }` option:

```ts
type Foo = () => void;

type Foo = (name: string) => string;

class Person {}

type Foo = (name: string, age: number) => string | Person;

type Foo = (name: string, age: number) => string & Person;
```

### `allowConditionalTypes`

This applies to conditional types.

Examples of **correct** code for the `{ "allowConditionalTypes": "always" }` option:

```ts
type Foo<T> = T extends number ? number : null;
```

### `allowConstructors`

This applies to constructor types.

The setting accepts the following values:

- `"always"` or `"never"` to active or deactivate the feature.

Examples of **correct** code for the `{ "allowConstructors": "always" }` option:

```ts
type Foo = new () => void;
```

### `allowLiterals`

This applies to literal types (`type Foo = { ... }`).

The setting accepts the following options:

- `"always"` or `"never"` to active or deactivate the feature.
- `"in-unions"`, allows literals in union statements, e.g. `type Foo = string | string[];`
- `"in-intersections"`, allows literals in intersection statements, e.g. `type Foo = string & string[];`
- `"in-unions-and-intersections"`, allows literals in union and/or intersection statements.

Examples of **correct** code for the `{ "allowLiterals": "always" }` options:

```ts
type Foo = {};

type Foo = {
  name: string;
  age: number;
};

type Foo = {
  name: string;
  age: number;
  walk: (miles: number) => void;
};

type Foo = { name: string } | { age: number };

type Foo = { name: string } & { age: number };
```

Examples of **incorrect** code for the `{ "allowLiterals": "in-unions" }` option:

```ts
type Foo = {};

type Foo = {
  name: string;
  age: number;
};

type Foo = {
  name: string;
  age: number;
  walk: (miles: number) => void;
};

type Foo = { name: string } & { age: number };
```

Examples of **correct** code for the `{ "allowLiterals": "in-unions" }` option:

```ts
type Foo = { name: string } | { age: number };
```

Examples of **incorrect** code for the `{ "allowLiterals": "in-intersections" }` option:

```ts
type Foo = {};

type Foo = {
  name: string;
  age: number;
};

type Foo = {
  name: string;
  age: number;
  walk: (miles: number) => void;
};

type Foo = { name: string } | { age: number };
```

Examples of **correct** code for the `{ "allowLiterals": "in-intersections" }` option:

```ts
type Foo = { name: string } & { age: number };
```

Examples of **incorrect** code for the `{ "allowLiterals": "in-unions-and-intersections" }` option:

```ts
type Foo = {};

type Foo = {
  name: string;
  age: number;
};

type Foo = {
  name: string;
  age: number;
  walk: (miles: number) => void;
};
```

Examples of **correct** code for the `{ "allowLiterals": "in-unions-and-intersections" }` option:

```ts
type Foo = { name: string } | { age: number };

type Foo = { name: string } & { age: number };
```

### `allowMappedTypes`

This applies to literal types.

The setting accepts the following values:

- `"always"` or `"never"` to active or deactivate the feature.
- `"in-unions"`, allows aliasing in union statements, e.g. `type Foo = string | string[];`
- `"in-intersections"`, allows aliasing in intersection statements, e.g. `type Foo = string & string[];`
- `"in-unions-and-intersections"`, allows aliasing in union and/or intersection statements.

Examples of **correct** code for the `{ "allowMappedTypes": "always" }` options:

```ts
type Foo<T> = { readonly [P in keyof T]: T[P] };

type Foo<T> = { [P in keyof T]?: T[P] };

type Foo<T, U> =
  | { readonly [P in keyof T]: T[P] }
  | { readonly [P in keyof U]: U[P] };

type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };

type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
  readonly [P in keyof U]: U[P];
};

type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
```

Examples of **incorrect** code for the `{ "allowMappedTypes": "in-unions" }` option:

```ts
type Foo<T> = { readonly [P in keyof T]: T[P] };

type Foo<T> = { [P in keyof T]?: T[P] };

type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
  readonly [P in keyof U]: U[P];
};

type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
```

Examples of **correct** code for the `{ "allowMappedTypes": "in-unions" }` option:

```ts
type Foo<T, U> =
  | { readonly [P in keyof T]: T[P] }
  | { readonly [P in keyof U]: U[P] };

type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
```

Examples of **incorrect** code for the `{ "allowMappedTypes": "in-intersections" }` option:

```ts
type Foo<T> = { readonly [P in keyof T]: T[P] };

type Foo<T> = { [P in keyof T]?: T[P] };

type Foo<T, U> =
  | { readonly [P in keyof T]: T[P] }
  | { readonly [P in keyof U]: U[P] };

type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
```

Examples of **correct** code for the `{ "allowMappedTypes": "in-intersections" }` option:

```ts
type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
  readonly [P in keyof U]: U[P];
};

type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
```

Examples of **incorrect** code for the `{ "allowMappedTypes": "in-unions-and-intersections" }` option:

```ts
type Foo<T> = { readonly [P in keyof T]: T[P] };

type Foo<T> = { [P in keyof T]?: T[P] };
```

Examples of **correct** code for the `{ "allowMappedTypes": "in-unions-and-intersections" }` option:

```ts
type Foo<T, U> =
  | { readonly [P in keyof T]: T[P] }
  | { readonly [P in keyof U]: U[P] };

type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };

type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
  readonly [P in keyof U]: U[P];
};

type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
```

### `allowTupleTypes`

This applies to tuple types (`type Foo = [number]`).

The setting accepts the following options:

- `"always"` or `"never"` to active or deactivate the feature.
- `"in-unions"`, allows tuples in union statements, e.g. `type Foo = [string] | [string, string];`
- `"in-intersections"`, allows tuples in intersection statements, e.g. `type Foo = [string] & [string, string];`
- `"in-unions-and-intersections"`, allows tuples in union and/or intersection statements.

Examples of **correct** code for the `{ "allowTupleTypes": "always" }` options:

```ts
type Foo = [number];

type Foo = [number] | [number, number];

type Foo = [number] & [number, number];

type Foo = [number] | ([number, number] & [string, string]);
```

Examples of **incorrect** code for the `{ "allowTupleTypes": "in-unions" }` option:

```ts
type Foo = [number];

type Foo = [number] & [number, number];

type Foo = [string] & [number];
```

Examples of **correct** code for the `{ "allowTupleTypes": "in-unions" }` option:

```ts
type Foo = [number] | [number, number];

type Foo = [string] | [number];
```

Examples of **incorrect** code for the `{ "allowTupleTypes": "in-intersections" }` option:

```ts
type Foo = [number];

type Foo = [number] | [number, number];

type Foo = [string] | [number];
```

Examples of **correct** code for the `{ "allowTupleTypes": "in-intersections" }` option:

```ts
type Foo = [number] & [number, number];

type Foo = [string] & [number];
```

Examples of **incorrect** code for the `{ "allowTupleTypes": "in-unions-and-intersections" }` option:

```ts
type Foo = [number];

type Foo = [string];
```

Examples of **correct** code for the `{ "allowLiterals": "in-unions-and-intersections" }` option:

```ts
type Foo = [number] & [number, number];

type Foo = [string] | [number];
```

### `allowGenerics`

This applies to generic types, including TypeScript provided global utility types (`type Foo = Record<string, number>`).

The setting accepts the following options:

- `"always"` or `"never"` to active or deactivate the feature.

Examples of **correct** code for the `{ "allowGenerics": "always" }` options:

```ts
type Foo = Bar<string>;

type Foo = Record<string, number>;

type Foo = Readonly<Bar>;

type Foo = Partial<Bar>;

type Foo = Omit<Bar, 'a' | 'b'>;
```

## When Not To Use It

When you can't express some shape with an interface or you need to use a union, tuple type,
callback, etc. that would cause the code to be unreadable or impractical.

## Further Reading

- [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html)
