npm package: @kiruse/metatypes
Description: Additional useful general-purpose MetaTypes for type manipulation & mapping.
Author: Kiruse
Latest version: 0.1.1

# MetaTypes.ts
Additional useful general purpose MetaTypes for type manipulation &amp; mapping.

No dependencies other than [TypeScript](https://www.typescriptlang.org).

**Note:** I will add more meta types as my need for them arises.

# Table of Contents
- [MetaTypes.ts](#metatypests)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Usage](#usage)
- [Types](#types)
  - [`Defined<T>`](#definedt)
  - [`DefinedProps<T, P extends keyof T = keyof T>`](#definedpropst-p-extends-keyof-t--keyof-t)
  - [`Prefix<T, P extends string>`](#prefixt-p-extends-string)
  - [`Retype<O, T, K extends keyof O = keyof O>`](#retypeo-t-k-extends-keyof-o--keyof-o)
  - [`ExtractByPrefix<T, P extends string>`](#extractbyprefixt-p-extends-string)

# Installation
Install via npm:

```shell
npm i --save-dev @kiruse/metatypes
```

or via yarn:

```shell
yarn add @kiruse/metatypes
```

# Usage
All exports of this package are type definitions. While usually negligible, it's advised to `import type` like such:

```typescript
import type { Retype } from '@kiruse/metatypes';
```

`import type` allows importing type definitions only relevant to the compilation process. The TypeScript compiler (`tsc`) can thus completely remove these imports from the compiled JavaScript sources. *MetaTypes* hence becomes a vanity dependency.

# Types

## `Defined<T>`
Removes `undefined` and `null` from `T`. It is similar in nature to TypeScript's built-in `Required`.

**Note:** TypeScript will only complain about values being potentially `null` or `undefined` with the `strictNullCheck` compiler option enabled.

**Example:**
```typescript
type SomeType = string | undefined | null;

var myGlobal: SomeType = undefined;

// Enforces that `v` must not be `undefined` or `null`.
function set(v: Defined<SomeType>) {
  myGlobal = v;
}
```

## `DefinedProps<T, P extends keyof T = keyof T>`
Removes `undefined` and `null` from all (named) properties of `T`.

Differs from TypeScript's built-in `Required` in that `Required` only removes the "optional/omittable" flag from the property, whereas `DefinedProps` removes this flag as well as `undefined` and `null` from the type.

**Note:** TypeScript will only complain about values being potentially `null` or `undefined` with the `strictNullCheck` compiler option enabled.

**Example:**
```typescript
type MyType = {
  foo?: number | null;
}
// equivalent to
type MyType = {
  foo: number | undefined | null;
} | {};

type MyRequiredType = Required<MyType>;
// equivalent to
type MyRequiredType = {
  foo: number | null;
}

type MyDefinedPropsType = DefinedProps<MyType>;
// equivalent to
type MyDefinedPropsType = {
  foo: number;
}
```

## `Prefix<T, P extends string>`
Prefix all properties of `T` with `P`, retaining their original type. The properties will be capitalized to adhere to camel-casing.

**Example:**
```typescript
type MyType = {
  foo: string;
  bar: number;
}

type Prefixed = Prefix<MyType, 'on'>;
// equivalent to
type Prefixed = {
  onFoo: string;
  onBar: number;
}
```

## `Retype<O, T, K extends keyof O = keyof O>`
Map properties of `O` to new type `T`, optionally filtered to only properties specified by `K`.

**Example:**
```typescript
type MyType = {
  foo: string;
  bar: number;
}

type MyTypeBool = Retype<MyType, boolean>;
// equivalent to
type MyTypeBool = {
  foo: boolean;
  bar: boolean;
}

type SelectiveRetype = Retype<MyType, symbol, 'bar'>;
// equivalent to
type SelectiveRetype = {
  foo: string;
  bar: symbol;
}
```

## `ExtractByPrefix<T, P extends string>`
Extract a subtype of `T` which contains only (string) properties prefixed with `P`.

**Example:**
```typescript
type MyType = {
  foo: string;
  onFoo: Function;
  bar: number;
  onBar: Function;
};

type MyEvents = ExtractByPrefix<MyType, 'on'>;

const events: MyEvents = {
  onFoo: () => {},
  onBar: () => {},
  bar: 42, // TSC issue!
};
```