An open API service indexing awesome lists of open source software.

https://github.com/eth-p/unnarrowed-ts

A type-only TypeScript library for detecting unnarrowed types and asserting narrowing of generic types.
https://github.com/eth-p/unnarrowed-ts

Last synced: 11 months ago
JSON representation

A type-only TypeScript library for detecting unnarrowed types and asserting narrowing of generic types.

Awesome Lists containing this project

README

          

# narrowable

A type-only TypeScript library for detecting unnarrowed types and asserting narrowing of generic types.

## What can I do with this?

- **[Associated types.](./examples/associated-types.ts)**
- **[Type narrowing assertions.](./examples/asserted-narrow.ts)**
- [Detecting when `infer T` uses the `extends` type as a fallback.](./examples/infer-fallback.ts)

## Types

### Unnarrowed

A type that has not been narrowed yet.

```ts
type Unnarrowed
```

**Usage:**

```ts
interface AssociatedTypes {
DateType: Unnarrowed
}
```

### NarrowedFrom

The narrowed form of an [`Unnarrowed`](#unnarrowed) type.

If used on the right-hand side of an `extends` statement such as
`MyClass>` where `T` is `Unnarrowed`, it will cause an
error when `U = T`.

```ts
type NarrowedFrom
```

**Behavior:**

* If `T` is `Unnarrowed`, returns `U`.
* If `T` is an object with `Unnarrowed` properties, the `Unnarrowed` is stripped from them.
* Otherwise, returns an *error type*.

**Usage:**

```ts
type DateType = Unnarrowed
type DateGetter = NarrowedFrom> = () => T;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <-- assert narrowing

/** Defined elsewhere */
declare function getPublishDate(package: string): DateType;

/**
* Prints a date returned by a DateGetter.
*/
function printDateFrom(getter: F) {
console.log(getter());
}

printDateFrom(() => new Date()); // ok
printDateFrom(() => getPublishDate("unnarrowed"));
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <-- error, it returns unnarrowed DateType
```

### AssertNarrowed

Asserts that the given type has been narrowed from an `Unnarrowed`.

```ts
type AssertNarrowed
```

**Options:**

```ts
{

// If set to `true`, the assertion will only pass if the type is
// narrowed to a single, non-union type.
strict?: true | false

// If set, this type will be returned when the assertion fails.
failType: any;

}
```

**Usage:**

```ts
type GlasswareMaterial = Unnarrowed<'glass' | 'crystal'>;
interface Glassware {
type: AssertNarrowed
}
const aWineGlass: Glassware<'glass' | 'crystal'> = {
type: "glass"
// ~~~~ <-- T is not strictly narrowed, so `type` is never
}
```

### AssertStrictlyNarrowed

An alias for [`AssertNarrowed`](#assertnarrowed) with the `strict` option set to `true`.

```ts
type AssertStrictlyNarrowed
```

## Utility Types

### IsUnnarrowed

Checks if a type is [`Unarrowed`](#unnarrowed).

If the given type is `any`, an *error type* will be returned.

```ts
type IsUnnarrowed
```

**Usage:**

```ts
type should_be_true = IsUnnarrowed>;
type should_be_false = IsUnnarrowed;
type is_error = IsUnnarrowed;
```

### IsNarrowed

Checks if a type is not [`Unarrowed`](#unnarrowed).

If the given type is `any`, the `WhenTrue` type will be returned.

```ts
type IsUnnarrowed
```

**Usage:**

```ts
type should_be_true = IsNarrowed;
type should_be_false = IsNarrowed>;
type also_true = IsNarrowed;
```

### IsStrictlyNarrowed

Checks if a type is not [`Unarrowed`](#unnarrowed), and is not a type union.

If the given type is `any`, the `WhenFalse` type will be returned.

```ts
type IsUnnarrowed
```

**Usage:**

```ts
type should_be_true = IsStrictlyNarrowed;
type should_be_false = IsStrictlyNarrowed>;
type also_false_1 = IsStrictlyNarrowed;
type also_false_2 = IsStrictlyNarrowed;
```