import { identity } from './function' export interface Newtype { readonly _URI: URI readonly _A: A } export type AnyNewtype = Newtype export interface Constructor { URI: URI wrap: (_: T) => Newtype unwrap: (_: Newtype) => T } export interface GenericConstructor { URI: URI wrap: (_: T) => Newtype unwrap: (_: Newtype) => T of: () => Constructor } export interface ConstructorK> { wrap: (_: T) => K unwrap: (_: K) => T } export const typeDef = () => (URI: URI): Constructor => ({ URI, wrap: identity as any, unwrap: identity as any }) export const genericDef = (URI: URI): GenericConstructor => ({ URI, wrap: identity as any, unwrap: identity as any, of: () => ({ URI, wrap: identity as any, unwrap: identity as any }) }) export const newtype = >() => ( _: Constructor ): ConstructorK => _ as any export type TypeOf> = [T] extends [Constructor] ? Newtype : never export type Generic> = [K] extends [GenericConstructor] ? Newtype : never