UNPKG

2.97 kBPlain TextView 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/**
19 * Given a type `T` representing instances of a class `C`, the type
20 * `Constructor<T>` is the type of the class `C`.
21 *
22 * This type emulates
23 * [Class<T> from Flow]{@link https://flow.org/en/docs/types/utilities/#classt-a-classtoc-idtoc-class-hreftoc-classa}.
24 *
25 * Note that in TypeScript constructors can also be `protected` or `private`
26 * and unfortunately specifying `{ new(): T }` is thus insufficient.
27 * Which is why, for classes without a public constructor, we have to
28 * specify a `_funErasure` (static) member as a property, to help the compiler
29 * infer type `T`.
30 *
31 * Example:
32 *
33 * ```typescript
34 * class NumBox { constructor(public num: number) {} }
35 * class GenBox<A> { constructor(public a: A) {} }
36 *
37 * function getDefault<F>(ref: Constructor<F>): Option<F> {
38 * if ((ref as any)._default) return Some(ref._default)
39 * return None
40 * }
41 *
42 * (NumBox as any)._default = new NumBox(10)
43 * (GenBox as any)._default = new GenBox("value")
44 *
45 * const r1: Option<NumBox> = getDefault(NumBox)
46 * const r2: Option<GenBox<any>> = getDefault(GenBox)
47 * ```
48 *
49 * And for classes with a private constructor:
50 *
51 * ```typescript
52 * class PrivateBox<A> {
53 * private constructor(public a: A) {}
54 *
55 * static _funErasure: PrivateBox<any> // leaving undefined
56 * }
57 *
58 * const F = PrivateBox as any
59 * F._default = new F("hello")
60 *
61 * const r: Option<PrivateBox<any>> = getDefault(NumBox)
62 * ```
63 */
64export type Constructor<T> =
65 { new(...args: any[]): T } | { readonly _Class: T }
66
67/**
68 * Lightweight encoding for higher kinded types.
69 *
70 * Inspired by the
71 * [Lightweight higher-kinded polymorphism]{@link https://www.cl.cam.ac.uk/~jdy22/papers/lightweight-higher-kinded-polymorphism.pdf}
72 * paper.
73 *
74 * Built to be compatible with other projects in the ecosystem.
75 */
76export interface HK<URI, A> {
77 readonly _URI: URI
78 readonly _A: A
79}
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/**
92 * Lightweight encoding for higher kinded types, the version for data
93 * types with two type parameters.
94 *
95 * See {@link HK} and {@link HK2}.
96 */
97export interface HK3<URI, U, L, A> extends HK2<URI, L, A> {
98 readonly _U: U
99}