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.
- Host: GitHub
- URL: https://github.com/eth-p/unnarrowed-ts
- Owner: eth-p
- License: mit
- Created: 2024-04-27T21:39:51.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-04-28T02:19:41.000Z (about 2 years ago)
- Last Synced: 2025-07-09T03:08:44.091Z (11 months ago)
- Language: JavaScript
- Size: 7.81 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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;
```