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 | */
|
63 | export 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 | */
|
77 | export 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 | */
|
87 | export 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 | */
|
96 | export interface HK3<URI, U, L, A> extends HK2<URI, L, A> {
|
97 | readonly _U: U;
|
98 | }
|