typelevel-ts
Advanced tools
Comparing version 0.3.5 to 0.4.0
@@ -16,2 +16,9 @@ # Changelog | ||
# 0.4.0 | ||
- **Breaking Change** | ||
- remove `Omit` type, use built-in instead (@gcanti) | ||
- **Bug Fix** | ||
- rewrite `Overwrite` definition using built-in `Omit`, fix #43 (@looading) | ||
# 0.3.5 | ||
@@ -18,0 +25,0 @@ |
@@ -0,1 +1,7 @@ | ||
/** | ||
* @since 0.3.0 | ||
*/ | ||
/** | ||
* @since 0.3.0 | ||
*/ | ||
export declare type Compact<A> = { | ||
@@ -6,11 +12,29 @@ [K in keyof A]: A[K]; | ||
* Returns the string literal 'T' if `A` and `B` are equal types, 'F' otherwise | ||
* | ||
* @example | ||
* import { Equals } from 'typelevel-ts' | ||
* | ||
* export type Result1 = Equals<string, string> // "T" | ||
* export type Result2 = Equals<string, number> // "F" | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type Equals<A, B> = (<C>() => C extends Compact<A> ? 'T' : 'F') extends (<C>() => C extends Compact<B> ? 'T' : 'F') ? 'T' : 'F'; | ||
export declare type Equals<A, B> = (<C>() => C extends Compact<A> ? 'T' : 'F') extends <C>() => C extends Compact<B> ? 'T' : 'F' ? 'T' : 'F'; | ||
/** | ||
* Extracts a super-type of `A` identified by its keys `K` | ||
* @example | ||
* import { Overwrite } from 'typelevel-ts' | ||
* | ||
* export type Result = Overwrite<{ a: string; b: number }, { b: boolean }> // { a: string; b: boolean } | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type Omit<A extends object, K extends string | number | symbol> = Pick<A, Exclude<keyof A, K>>; | ||
export declare type Overwrite<A extends object, B extends object> = Compact<{ | ||
[K in Exclude<keyof A, keyof B>]: A[K]; | ||
} & B>; | ||
export declare type Overwrite<A extends object, B extends object> = Compact<Omit<A, keyof B> & B>; | ||
/** | ||
* @example | ||
* import { Diff } from 'typelevel-ts' | ||
* | ||
* export type Result = Diff<{ a: string; b: number }, 'b'> // { a: string; b?: number } | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type Diff<A extends object, OK extends keyof A> = Compact<{ | ||
@@ -23,2 +47,9 @@ [K in Exclude<keyof A, OK>]: A[K]; | ||
* Picks only the keys of a certain type | ||
* | ||
* @example | ||
* import { KeysOfType } from 'typelevel-ts' | ||
* | ||
* export type Result = KeysOfType<{a: string, b: string | boolean, c: boolean, d: string}, string> // "a" | "d" | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
@@ -29,18 +60,93 @@ export declare type KeysOfType<A extends object, B> = { | ||
/** | ||
* Encodes the constraint that a given object `A` | ||
* does not contain specific keys `K` | ||
* Encodes the constraint that a given object `A` does not contain specific keys `K` | ||
* | ||
* @example | ||
* import { RowLacks } from 'typelevel-ts' | ||
* | ||
* // function f(x: RowLacks<{ a: string; b: number }, 'a' | 'b'>): void {} | ||
* // $ExpectError | ||
* // f({ a: 'a', b: 1 }) | ||
* function g(x: RowLacks<{ a: string; b: number }, 'c'>): void {} | ||
* g({ a: 'a', b: 1 }) // ok | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type RowLacks<A extends object, K extends string | number | symbol> = A & Record<Extract<keyof A, K>, never>; | ||
/** | ||
* @example | ||
* import { Exact } from 'typelevel-ts' | ||
* | ||
* function f<T extends Exact<{ a: string }, T>>(a: T): void {} | ||
* f({ a: 'a' }) | ||
* // $ExpectError | ||
* // f({ a: 'a', b: 1 }) | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type Exact<A extends object, B extends A> = A & Record<Exclude<keyof B, keyof A>, never>; | ||
/** | ||
* @example | ||
* import { AnyTuple } from 'typelevel-ts' | ||
* | ||
* function f<T extends AnyTuple>(x: T): T { | ||
* return x | ||
* } | ||
* const x: [number] = [1] | ||
* const y: [number, string] = [1, 'a'] | ||
* const z: [number, string, boolean] = [1, 'a', true] | ||
* f(x) | ||
* f(y) | ||
* f(z) | ||
* // $ExpectError | ||
* // f([1, 2, 3]) | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type AnyTuple = Array<any> & { | ||
'0': any; | ||
}; | ||
/** | ||
* @internal | ||
* @since 0.3.0 | ||
*/ | ||
export interface DeepReadonlyArray<A> extends ReadonlyArray<DeepReadonly<A>> { | ||
} | ||
/** | ||
* @internal | ||
* @since 0.3.0 | ||
*/ | ||
export declare type DeepReadonlyObject<A> = { | ||
readonly [K in keyof A]: DeepReadonly<A[K]>; | ||
}; | ||
/** | ||
* @example | ||
* import { DeepReadonly } from 'typelevel-ts' | ||
* | ||
* interface Foo { | ||
* bar: { | ||
* baz: string | ||
* quux: Array<{ barbaz: number }> | ||
* } | ||
* } | ||
* | ||
* type ReadonlyFoo = DeepReadonly<Foo> | ||
* export declare const x: ReadonlyFoo | ||
* // $ExpectError | ||
* // x.bar.quux[1].barbaz = 1 | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
export declare type DeepReadonly<A> = A extends Array<infer B> ? DeepReadonlyArray<B> : DeepReadonlyObject<A>; | ||
/** | ||
* Extracts the type of a member of a tagged union | ||
* | ||
* @example | ||
* import { TaggedUnionMember } from 'typelevel-ts' | ||
* | ||
* type A = { tag: 'A'; a: string } | ||
* type B = { tag: 'B'; b: number } | ||
* type C = A | B | ||
* export type Result = TaggedUnionMember<C, 'tag', 'A'> // A | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
@@ -50,2 +156,10 @@ export declare type TaggedUnionMember<A extends object, Tag extends keyof A, Value extends A[Tag]> = Extract<A, Record<Tag, Value>>; | ||
* Extracts required keys as a literal type union | ||
* | ||
* @example | ||
* import { RequiredKeys } from 'typelevel-ts' | ||
* | ||
* type A = { a: string; b: number; x?: string; y?: number } | ||
* export type Result = RequiredKeys<A> // "a" | "b" | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
@@ -59,2 +173,10 @@ export declare type RequiredKeys<T> = { | ||
* Extracts optional keys as a literal type union | ||
* | ||
* @example | ||
* import { OptionalKeys } from 'typelevel-ts' | ||
* | ||
* type A = { a: string; b: number; x?: string; y?: number } | ||
* export type Result = OptionalKeys<A> // "x" | "y" | ||
* | ||
* @since 0.3.0 | ||
*/ | ||
@@ -61,0 +183,0 @@ export declare type OptionalKeys<T> = { |
"use strict"; | ||
/** | ||
* @since 0.3.0 | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "typelevel-ts", | ||
"version": "0.3.5", | ||
"version": "0.4.0", | ||
"description": "Type level programming in TypeScript", | ||
@@ -14,6 +14,7 @@ "files": [ | ||
"fix-prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --write \"{src,typings-checker}/**/*.ts\"", | ||
"test": "npm run prettier && npm run lint && npm run dtslint", | ||
"test": "npm run prettier && npm run lint && npm run dtslint && npm run docs", | ||
"clean": "rm -rf lib/*", | ||
"build": "npm run clean && tsc", | ||
"dtslint": "dtslint dtslint" | ||
"dtslint": "dtslint dtslint", | ||
"docs": "docs-ts" | ||
}, | ||
@@ -33,8 +34,9 @@ "repository": { | ||
"@types/react": "^16.3.17", | ||
"dtslint": "^0.4.2", | ||
"prettier": "^1.14.3", | ||
"docs-ts": "^0.3.0", | ||
"dtslint": "github:gcanti/dtslint", | ||
"prettier": "^1.19.1", | ||
"react": "^16.4.0", | ||
"tslint": "4.4.2", | ||
"tslint-config-standard": "4.0.0", | ||
"typescript": "^3.1.1" | ||
"typescript": "^3.7.4" | ||
}, | ||
@@ -41,0 +43,0 @@ "tags": [], |
117
README.md
# TypeScript compatibility | ||
The stable version is tested against TypeScript 2.9.1+ | ||
| `typelevel-ts` version | required `typescript` version | | ||
| ---------------------- | ----------------------------- | | ||
| 0.4.x | 3.5+ | | ||
| 0.3.x | 2.9.1+ | | ||
# API | ||
# Documentation | ||
## Equals<A, B> | ||
Returns the string literal 'T' if `A` and `B` are equal types, 'F' otherwise | ||
```ts | ||
Equals<string, string> // "T" | ||
Equals<string, number> // "F" | ||
``` | ||
## Omit<A extends object, K extends string | number | symbol> | ||
Extracts a super-type of `A` identified by its keys `K` | ||
```ts | ||
Omit<{ a: string; b: number }, 'a'> // { b: number } | ||
``` | ||
## Overwrite<A extends object, B extends object> | ||
```ts | ||
Overwrite<{ a: string; b: number }, { b: boolean }> // { a: string; b: boolean } | ||
``` | ||
## Diff<A extends object, K extends keyof A> | ||
```ts | ||
Diff<{ a: string; b: number }, 'b'> // { a: string; b?: number } | ||
``` | ||
## RowLacks<A extends object, K extends string | number | symbol> | ||
Encodes the constraint that a given object `A` does not contain specific keys `K` | ||
```ts | ||
declare function f(x: RowLacks<{ a: string; b: number }, 'a'>): void | ||
// $ExpectError | ||
f({ a: 'foo', b: 1 }) | ||
``` | ||
## Exact<A extends object, B extends A> | ||
```ts | ||
declare function f<T extends Exact<{ a: string }, T>>(a: T): void | ||
declare const x: { a: string } | ||
declare const y: { a: string; b: number } | ||
f(x) | ||
// $ExpectError | ||
f(y) | ||
``` | ||
## KeysOfType<A extends object, B> | ||
Picks only the keys of a certain type | ||
```ts | ||
KeysOfType<{a: string, b: string | boolean, c: boolean, d: string}, string> // "a" | "d" | ||
``` | ||
## AnyTuple | ||
```ts | ||
declare function f<T extends AnyTuple>(x: T): T | ||
declare const x: [number] | ||
declare const y: [number, string] | ||
declare const z: [number, string, boolean] | ||
declare const t: Array<number> | ||
f(x) | ||
f(y) | ||
f(z) | ||
// $ExpectError | ||
f(t) | ||
``` | ||
## DeepReadonly<A> | ||
```ts | ||
interface Foo { | ||
bar: { | ||
baz: string | ||
quux: Array<{ barbaz: number }> | ||
} | ||
} | ||
type ReadonlyFoo = DeepReadonly<Foo> | ||
declare const x: ReadonlyFoo | ||
// $ExpectError | ||
x.bar.quux[1].barbaz = 1 | ||
``` | ||
## TaggedUnionMember<A extends object, Tag extends keyof A, Value extends A[Tag]> | ||
Extracts the type of a member of a tagged union | ||
```ts | ||
type A = { tag: 'A'; a: string } | ||
type B = { tag: 'B'; b: number } | ||
type C = A | B | ||
TaggedUnionMember<C, 'tag', 'A'> // A | ||
``` | ||
## RequiredKeys<A extends object> and OptionalKeys<A extends object> | ||
Extracts required or optional keys as a literal type union | ||
```ts | ||
type A = { a: string; b: number; x?: string; y?: number } | ||
RequiredKeys<A> // "a" | "b" | ||
OptionalKeys<A> // "x" | "y" | ||
``` | ||
- [API Reference](https://gcanti.github.io/typelevel-ts) |
Sorry, the diff of this file is not supported yet
9551
187
8
11