Skip to content
This repository was archived by the owner on Dec 7, 2024. It is now read-only.

Commit 193a5f7

Browse files
committed
Switch to non-ambient module
1 parent be90cc1 commit 193a5f7

File tree

15 files changed

+180
-172
lines changed

15 files changed

+180
-172
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
.vscode
22
.build
33
node_modules
4-
future/

examples/abstract/nullable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { unknown } from "typeprops";
1+
import { unknown } from "../..";
22
import { StaticFunctor } from "../../lib/abstract/functor";
33
import { test } from "../../tests/harness";
44

examples/pattern-matching/adt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Generic, Parameter } from "typeprops";
1+
import { Generic, Parameter } from "../..";
22

33
export interface MonadProps<T, Params extends ArrayLike<any>> {}
44

examples/pattern-matching/either.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Based on provided sample by Asad Saeeduddin
2-
import { Parameter, unknown } from "typeprops";
2+
import { Parameter, unknown } from "../..";
33
import { test } from "../../tests/harness";
44
import { GenericMonad, Matchable, Monad } from "./adt";
55
import { Maybe, None, maybe } from "./maybe";

index.d.ts

Lines changed: 0 additions & 152 deletions
This file was deleted.

index.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { Match } from "./match";
2+
3+
// Waiting for proper top type
4+
export type unknown = {} | null | undefined;
5+
6+
// TODO: TS 2.9: add symbol support
7+
export interface TypeProp {
8+
infer: ArrayLike<unknown>;
9+
construct: unknown;
10+
}
11+
12+
export { Match } from "./match";
13+
14+
/**
15+
* Get the type parameters for type T
16+
*
17+
* 'T' is the type to get parameters for
18+
* 'Override' optionally allows you to override select types in the type dictionary
19+
*/
20+
export type Parameters<
21+
T,
22+
Override extends { [K in keyof Override]: TypeProp } = never
23+
> = Match<T, never, Override>["infer"];
24+
25+
/**
26+
* Get a type parameter for type T
27+
*
28+
* 'T' is the type to get the parameter for
29+
* 'Index' optionally allows you to specify which parameter to return
30+
* 'Override' optionally allows you to override select types in the type dictionary
31+
*/
32+
export type Parameter<
33+
T,
34+
Index extends number = 0,
35+
Override extends { [K in keyof Override]: TypeProp } = never
36+
> = Parameters<T, Override>[Index];
37+
38+
/**
39+
* Get a concrete generic type mutated from type T, with Params
40+
*
41+
* 'T' is the type to mutate
42+
* 'Params' is the array of type parameters to mutate into, defaults to 'ArrayLike<any>'
43+
* 'Override' optionally allows you to override select types in the type dictionary
44+
*/
45+
export type Generic<
46+
T,
47+
Params extends ArrayLike<any> = ArrayLike<any>,
48+
Override extends { [K in keyof Override]: TypeProp } = never
49+
> = Match<T, Params, Override>["construct"];
50+
51+
declare module "typeprops" {
52+
/**
53+
* A dictionary of 'TypeProps' that can be extended through [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces).
54+
*
55+
* 'T' is the type you want to check and/or mutate.
56+
* 'Params' is a list of type parameters to mutate 'T' with
57+
*
58+
* Each entry should have a unique key, typed with the following two properties:
59+
*
60+
* ```TypeScript
61+
* {
62+
* infer: T extends MyType<infer A> ? [A] : never;
63+
* construct: MyType<Params[0]>
64+
* }
65+
* ```
66+
*
67+
* 'infer' should always verify the type is correct and return 'never' otherwise. It should return an ArrayLike with a list of inferred type parameters.
68+
*
69+
* 'construct' should return the mutated type using the passed in 'Params'. It should generally not check if the passed in type 'T' is correct. If you want to reuse parameters from 'T', you can do it like this:
70+
*
71+
* ```TypeScript
72+
* {
73+
* infer: T extends MyType<any, infer A> ? [A] : never;
74+
* construct: MyType<Parameter<T, 0>, Params[0]>
75+
* }
76+
* ```
77+
*/
78+
interface TypeProps<T, Params extends ArrayLike<any>> {
79+
array: {
80+
infer: T extends Array<infer A> ? T : never;
81+
construct: Params[number][];
82+
};
83+
null: {
84+
infer: null extends T ? [never] : never;
85+
construct: null;
86+
};
87+
undefined: {
88+
infer: undefined extends T ? [never] : never;
89+
construct: undefined;
90+
};
91+
unfound: {
92+
infer: [NonNullable<T>];
93+
construct: Params[0];
94+
};
95+
}
96+
}

lib/abstract/functor.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import { FunctorProps, Generic, Parameter } from "typeprops";
1+
import { Generic, Parameter } from "../..";
22

3-
declare module "typeprops" {
4-
interface FunctorProps<T, Params extends ArrayLike<any>> {}
5-
}
3+
export interface FunctorProps<T, Params extends ArrayLike<any>> {}
64

75
export type GenericFunctor<F, A = any> = Generic<F, [A], FunctorProps<F, [A]>>;
86
export type FunctorParameter<F> = Parameter<F, 0, FunctorProps<F, any[]>>;

lib/abstract/monad.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { Generic, MonadProps, Parameter } from "typeprops";
1+
import { Generic, Parameter } from "../..";
2+
import { FunctorProps } from "./functor";
23

3-
declare module "typeprops" {
4-
interface MonadProps<T, Params extends ArrayLike<any>>
5-
extends FunctorProps<T, Params> {}
6-
}
4+
interface MonadProps<T, Params extends ArrayLike<any>>
5+
extends FunctorProps<T, Params> {}
76

87
export type GenericMonad<F, A = any> = Generic<F, [A], MonadProps<F, [A]>>;
98
export type MonadParameter<F> = Parameter<F, 0, MonadProps<F, [any]>>;

lib/data/either.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { unknown } from "typeprops";
1+
import { Parameter, unknown } from "../..";
22
import { Option } from "./option";
33
import { UnitLike } from "./unit";
44

@@ -11,7 +11,9 @@ declare module "typeprops" {
1111
construct: Either<Params[0], Params[1]>;
1212
};
1313
}
14+
}
1415

16+
declare module "../abstract/functor" {
1517
interface FunctorProps<T, Params> {
1618
[EitherId]: {
1719
infer: T extends Either<any, infer R> ? [R] : never;

lib/data/option.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { unknown } from "typeprops";
1+
import { unknown } from "../..";
22
import { Either, Left, Right } from "./either";
33
import { UnitLike } from "./unit";
44

lib/data/unit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { unknown } from "typeprops";
1+
import { unknown } from "../..";
22
import { Option } from "./option";
33

44
declare const UnitId = "typeprops/lib/data/unit";

match.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { TypeProps } from "typeprops";
2+
import { TypeProp } from ".";
3+
4+
/**
5+
* A type-level pattern-matcher. Returns a TypeProp for a type T, with Params, given:
6+
*
7+
* 'T' is the type to match against
8+
* 'Params' is the parameters you want to mutate T with
9+
* 'Override' lets you optionally define overrides for the type dictionary
10+
*
11+
* A rough overview of the algorithm:
12+
* - Split union type into distinct cases using a distributive conditional
13+
* - Construct a type dictionary using TypeProps & Override
14+
* - If T is '{}', set the checking type to 'any'
15+
* - Otherwise, set the checking type to the 'infer' property of T's TypeProp
16+
* - If the checking type is 'never', set the indexer to "unfound"
17+
* - Otherwise, use a mapped type to get the unique key for T's TypeProp, excluding "unfound" and set it as the indexer
18+
* - If the checking type was 'any', it will run both previous paths and return a union of "unfound" and all other unique keys as indexer
19+
* - Index the type dictionary with the indexer and return the TypeProp
20+
*/
21+
export type Match<
22+
T,
23+
Params extends ArrayLike<any> = ArrayLike<any>,
24+
Override extends { [K in keyof Override]: TypeProp } = never
25+
> = T extends infer U
26+
? Dictionary<U, Params, Override>[({} extends U
27+
? any
28+
: TypeProps<U, Params>[Exclude<
29+
keyof TypeProps<U, Params>,
30+
"unfound"
31+
>]["infer"]) extends never
32+
? "unfound"
33+
: {
34+
[Key in Exclude<
35+
keyof TypeProps<U, Params>,
36+
"unfound"
37+
>]: TypeProps<U, Params>[Key]["infer"] extends never
38+
? never
39+
: Key
40+
}[Exclude<keyof TypeProps<U, Params>, "unfound">]]
41+
: never;
42+
43+
/**
44+
* Construct a type dictionary
45+
*
46+
* 'T' is the type to mutate
47+
* 'Params' is the array of type parameters to mutate into
48+
* 'Override' optionally allows you to override select types in the type dictionary
49+
*/
50+
export type Dictionary<
51+
T,
52+
Params extends ArrayLike<any>,
53+
Override extends { [K in keyof Override]: TypeProp } = never
54+
> = {
55+
[K in
56+
| (keyof TypeProps<T, Params>)
57+
| keyof Override]: K extends keyof Override
58+
? Override[K]
59+
: K extends keyof TypeProps<T, Params> ? TypeProps<T, Params>[K] : never
60+
};

0 commit comments

Comments
 (0)