millsp / ts-toolbelt

šŸ‘· TypeScript's largest type utility library
https://millsp.github.io/ts-toolbelt/
Apache License 2.0
6.75k stars 148 forks source link

Extract unwrapped type from Any.Type #232

Open expelledboy opened 3 years ago

expelledboy commented 3 years ago

šŸ© Feature Request

How do you get the underlying type T from Any.Type<T>?

import { Test, Any } from "ts-toolbelt";

const {checks, check} = Test

type RootType = number;
type Wrapped = Any.Type<RootType>;
type Unwrapped = Any.ExtractType<Wrapped>; // This is what I am looking for

checks([
    check<Unwrapped, RootType, Test.Pass>(),
])

Heres an example of where you would use it:

import { Any } from "ts-toolbelt";
import { Either } from "fp-ts/lib/Either";

// The library exports the following API to create terms given a object containing values
// It returns the module but with the wrapped opaque sub-types
export type Term<T extends Record<string, any>> = {
  [K in keyof T]: Any.Type<T[K], K>;
};

// This is really what I would like to work, or ask if there is an existing feature
// This looks like it should work.. and I have tried messing around with this for the last 2 hours
type ExtractType<T extends Any.Type<infer V>> = V;

// I wish to export an additional API parameterized with a type created using Term/1
export type Encode<T extends Record<string, any>> = {
  [K in keyof T]: (value: ExtractType<T[K]>) => Either<Error, T[K]>;
};

Here is how I desire to use the above generic types:

import { Term, Encode } from "./library.d"
import * as E from "fp-ts/lib/Either";

type MyTerm = Term<{
  Age: number;
}>

// I want to type the encode function from number -> Any.Type<Number>, ignoring the Maybe
const encodeAge: Encode<MyTerm>["Age"] = (age) => {
  if (age < 0) return E.left(new Error("Age out of bounds"));
  else return E.right(age as MyTerm["Age"]);
};
expelledboy commented 3 years ago

It seems that Any.Type needs to store the base type in an sub property, as per https://github.com/kourge/ts-brand

See https://github.com/kourge/ts-brand/blob/80e34f96c9bc6658b45f13bdbb02279a47cc062d/src/index.ts#L44

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.