UNPKG

3 kBTypeScriptView Raw
1/*!
2 * Copyright (c) 2017-2018 by The Funfix Project Developers.
3 * Some rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17/**
18 * Given a type `T` representing instances of a class `C`, the type
19 * `Constructor<T>` is the type of the class `C`.
20 *
21 * This type emulates
22 * [Class<T> from Flow]{@link https://flow.org/en/docs/types/utilities/#classt-a-classtoc-idtoc-class-hreftoc-classa}.
23 *
24 * Note that in TypeScript constructors can also be `protected` or `private`
25 * and unfortunately specifying `{ new(): T }` is thus insufficient.
26 * Which is why, for classes without a public constructor, we have to
27 * specify a `_funErasure` (static) member as a property, to help the compiler
28 * infer type `T`.
29 *
30 * Example:
31 *
32 * ```typescript
33 * class NumBox { constructor(public num: number) {} }
34 * class GenBox<A> { constructor(public a: A) {} }
35 *
36 * function getDefault<F>(ref: Constructor<F>): Option<F> {
37 * if ((ref as any)._default) return Some(ref._default)
38 * return None
39 * }
40 *
41 * (NumBox as any)._default = new NumBox(10)
42 * (GenBox as any)._default = new GenBox("value")
43 *
44 * const r1: Option<NumBox> = getDefault(NumBox)
45 * const r2: Option<GenBox<any>> = getDefault(GenBox)
46 * ```
47 *
48 * And for classes with a private constructor:
49 *
50 * ```typescript
51 * class PrivateBox<A> {
52 * private constructor(public a: A) {}
53 *
54 * static _funErasure: PrivateBox<any> // leaving undefined
55 * }
56 *
57 * const F = PrivateBox as any
58 * F._default = new F("hello")
59 *
60 * const r: Option<PrivateBox<any>> = getDefault(NumBox)
61 * ```
62 */
63export declare type Constructor<T> = {
64 new (...args: any[]): T;
65} | {
66 readonly _Class: T;
67};
68/**
69 * Lightweight encoding for higher kinded types.
70 *
71 * Inspired by the
72 * [Lightweight higher-kinded polymorphism]{@link https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf}
73 * paper.
74 *
75 * Built to be compatible with other projects in the ecosystem.
76 */
77export interface HK<URI, A> {
78 readonly _URI: URI;
79 readonly _A: A;
80}
81/**
82 * Lightweight encoding for higher kinded types, the version for data
83 * types with two type parameters.
84 *
85 * See {@link HK} and {@link HK3}.
86 */
87export interface HK2<URI, L, A> extends HK<URI, A> {
88 readonly _L: L;
89}
90/**
91 * Lightweight encoding for higher kinded types, the version for data
92 * types with two type parameters.
93 *
94 * See {@link HK} and {@link HK2}.
95 */
96export interface HK3<URI, U, L, A> extends HK2<URI, L, A> {
97 readonly _U: U;
98}