import { fail , createScalarNode , SimpleType , TypeFlags , isType , IValidationContext , IValidationResult , typeCheckFailure , ModelType , typeCheckSuccess , ISimpleType , AnyObjectNode , ScalarNode , assertArg } from "../../internal" ; abstract class BaseIdentifierType < T > extends SimpleType < T , T , T > { readonly flags = TypeFlags . Identifier ; constructor ( name , private readonly validType ) { super ( name ) ; } instantiate ( parent , subpath , environment , initialValue ) { if ( ! parent || ! ( parent . type instanceof ModelType ) ) throw fail ( `Identifier types can only be instantiated as direct child of a model type` ) ; return createScalarNode ( this , parent , subpath , environment , initialValue ) ; } reconcile ( current , newValue , parent , subpath ) { if ( current . storedValue !== newValue ) throw fail ( `Tried to change identifier from '${ current . storedValue }' to '${ newValue }'. Changing identifiers is not allowed.` ) ; current . setParent ( parent , subpath ) ; return current ; } isValidSnapshot ( value , context ) { if ( typeof value !== this . validType ) { return typeCheckFailure ( context , value , `Value is not a valid ${ this . describe ( ) }, expected a ${ this . validType }` ) ; } return typeCheckSuccess ( ) ; } } internal hidden export class IdentifierType extends BaseIdentifierType < string > { readonly flags = TypeFlags . Identifier ; constructor ( ) { super ( `identifier` , "string" ) ; } describe ( ) { return `identifier` ; } } internal hidden export class IdentifierNumberType extends BaseIdentifierType < number > { constructor ( ) { super ( "identifierNumber" , "number" ) ; } getSnapshot ( node ) { return node . storedValue ; } describe ( ) { return `identifierNumber` ; } } returns export const identifier = new IdentifierType ( ) ; returns export const identifierNumber = new IdentifierNumberType ( ) ; param type returns export function isIdentifierType < IT extends typeof identifier | typeof identifierNumber > ( type ) { return isType ( type ) && ( type . flags & TypeFlags . Identifier ) > 0 ; } /**
 * Valid types for identifiers.
 */ export type ReferenceIdentifier = string | number ; internal hidden export function normalizeIdentifier ( id ) { return "" + id ; } internal hidden export function isValidIdentifier ( id ) { return typeof id === "string" || typeof id === "number" ; } internal hidden export function assertIsValidIdentifier ( id , argNumber ) { assertArg ( id , isValidIdentifier , "string or number (identifier)" , argNumber ) ; }