import { fromJSON, refer } from "./reference.ts"; export interface Entity> { "@": ToString>; } /** * Phantom string type that can captures type parameter. */ export type ToString = string & { toString(): ToString }; export const entity = >( description: NonNullable | null, ): Entity => { return { "@": refer(description).toJSON()["/"] }; }; export const toString = >( entity: Entity, ): string => `@${entity["@"]}`; export const fromString = >( source: string | ToString>, ): Entity => { if (!source.startsWith("@")) { throw new TypeError( `Expected formatted entity which starts with @ character instead got ${ JSON.stringify( source, ) }`, ); } else { return { "@": fromJSON({ "/": source.slice(1) }).toJSON()["/"] }; } }; /** * Asserts type of the `source` to be an `Entity`. */ export const is = >( source: unknown | Entity, ): source is Entity => source != null && typeof (source as { ["@"]?: string })["@"] === "string";