@@ -100,11 +100,6 @@ type ErrorMap = Record<
100100 }
101101> ;
102102
103- type FeatureFn < ErrorType extends string > = (
104- featureName : string ,
105- featureContextExtendedParams ?: ExtendedParams
106- ) => CreateErrorFn < ErrorType > ;
107-
108103type ErrorFnOptions = {
109104 originalError ?: OriginalError ;
110105 extendedParams ?: ExtendedParams ;
@@ -116,23 +111,34 @@ type CreateErrorFn<ErrorType extends string> = (
116111 options ?: ErrorFnOptions
117112) => IConwayError ;
118113
119- type ErrorSubcontext < ErrorType extends string > = {
114+ type Brand < T , B > = T & { __brand : B } ;
115+
116+ type ErrorSubcontext < Name extends string , ErrorType extends string > = Brand < Subcontext < Name , ErrorType > , Name > ;
117+ type ErrorFeature < Name extends string , ErrorType extends string > = Brand < CreateErrorFn < ErrorType > , Name > ;
118+
119+ type Subcontext < Name extends string , ErrorType extends string > = {
120120 /**
121121 * Create a child context within the current context.
122122 *
123123 * @param {string } childContextName - The name of the child context.
124124 * @param {ExtendedParams } extendedParams - Additional extended parameters for the child context.
125125 * @return {Function } Function to create an error context with the specified child context name and extended params.
126126 */
127- subcontext : ( subcontextName : string , extendedParams ?: ExtendedParams ) => ErrorSubcontext < ErrorType > ;
127+ subcontext : < const ChildContextName extends string > (
128+ subcontextName : ChildContextName ,
129+ extendedParams ?: ExtendedParams
130+ ) => ErrorSubcontext < `${Name } /${ChildContextName } `, ErrorType > ;
128131 /**
129132 * Creates a child feature within the current context.
130133 *
131134 * @param {string } childFeatureName - The name of the child feature.
132135 * @param {ExtendedParams } [extendedParams={}] - Additional extended parameters for the child feature.
133136 * @return {Function } The created error feature.
134137 */
135- feature : FeatureFn < ErrorType > ;
138+ feature : < const FeatureName extends string > (
139+ featureName : FeatureName ,
140+ featureContextExtendedParams ?: ExtendedParams
141+ ) => ErrorFeature < FeatureName , ErrorType > ;
136142} ;
137143
138144/**
@@ -146,7 +152,7 @@ export function createError<ErrorTypes extends ErrorTypeConfig>(errorTypes?: Err
146152 const _options = { ...defaultErrorOptions , ...options } ;
147153 const initialExtendedParams = options ?. extendedParams ?? { } ;
148154
149- return ( contextName : string , extendedParams : ExtendedParams = { } ) => {
155+ return < const ContextName extends string > ( contextName : ContextName , extendedParams : ExtendedParams = { } ) => {
150156 const outerExtendedParams = { ...initialExtendedParams , ...extendedParams } ;
151157
152158 const errorsMap : ErrorMap = Array . isArray ( errorTypes )
@@ -162,30 +168,37 @@ export function createError<ErrorTypes extends ErrorTypeConfig>(errorTypes?: Err
162168 const UnknownError = createErrorClass ( "UnknownError" , contextName ) ;
163169
164170 const _createSubcontext =
165- ( contextName : string , subContextExtendedParams : ExtendedParams ) =>
166- ( childContextName : string , extendedParams : ExtendedParams = { } ) => {
171+ < const ContextName extends string > ( contextName : ContextName , subContextExtendedParams : ExtendedParams ) =>
172+ < const ChildContextName extends string > (
173+ childContextName : ChildContextName ,
174+ extendedParams : ExtendedParams = { }
175+ ) => {
167176 const subErrorContext = { ...subContextExtendedParams , ...extendedParams } ;
168177 return _createErrorContext ( `${ contextName } /${ childContextName } ` , subErrorContext ) ;
169178 } ;
170179
171- function _createErrorContext (
172- _contextName : string ,
180+ function _createErrorContext < const ContextName extends string > (
181+ _contextName : ContextName ,
173182 contextExtendedParams : ExtendedParams = outerExtendedParams
174- ) : ErrorSubcontext < ErrorTypes [ number ] [ "errorType" ] > {
183+ ) : ErrorSubcontext < ContextName , ErrorTypes [ number ] [ "errorType" ] > {
175184 return {
185+ __brand : _contextName ,
176186 subcontext : _createSubcontext ( _contextName , contextExtendedParams ) ,
177- feature : ( childFeatureName : string , extendedParams : ExtendedParams = { } ) => {
187+ feature : < const FeatureName extends string > (
188+ childFeatureName : FeatureName ,
189+ extendedParams : ExtendedParams = { }
190+ ) => {
178191 const featureErrorContext = { ...contextExtendedParams , ...extendedParams } ;
179192 return _createErrorFeature ( childFeatureName , _contextName , featureErrorContext ) ;
180193 } ,
181194 } ;
182195 }
183196
184- function _createErrorFeature (
185- featureName : string ,
197+ function _createErrorFeature < const FeatureName extends string > (
198+ featureName : FeatureName ,
186199 contextName : string ,
187200 featureContextExtendedParams : ExtendedParams = { }
188- ) {
201+ ) : ErrorFeature < FeatureName , ErrorTypes [ number ] [ "errorType" ] > {
189202 const createNewErrorObject : CreateErrorFn < ErrorTypes [ number ] [ "errorType" ] > = (
190203 errorType ,
191204 message : string ,
@@ -215,7 +228,8 @@ export function createError<ErrorTypes extends ErrorTypeConfig>(errorTypes?: Err
215228 return error ;
216229 } ;
217230
218- return createNewErrorObject ;
231+ Object . assign ( createNewErrorObject , { __brand : featureName } ) ;
232+ return createNewErrorObject as ErrorFeature < FeatureName , ErrorTypes [ number ] [ "errorType" ] > ;
219233 }
220234
221235 return _createErrorContext ( contextName ) ;
0 commit comments