export function defineTag < T extends object > ( target , tag ) { Object . defineProperty ( target , Symbol . toStringTag , { writable : false , enumerable : false , configurable : true , value : tag } ) ; return target as T & { [ Symbol . toStringTag ] : string ; } ; } export function Tag ( tag ? ) { return function ( target ) { const tagString = tag || target . name ; if ( ! tagString ) throw new Error ( "Invalid tag" ) ; defineTag ( target . prototype , tagString ) ; } ; } export interface Tagged { [ Symbol . toStringTag ] : string ; }