3
3
*/
4
4
import { isString , get , isFunction , zipObject , isUndefined , assignInWith , aggregator , isObject } from './helpers' ;
5
5
6
- export function isActionSelector ( value : any ) : value is ActionSelector {
7
- return isObject ( value ) ;
8
- }
9
6
/**
10
7
* A Function invoked per iteration
11
8
* @param { } iteratee The current element to transform
@@ -31,8 +28,8 @@ export function isActionSelector(value: any): value is ActionSelector {
31
28
* ```
32
29
*
33
30
*/
34
- export interface ActionFunction < D , S > {
35
- ( iteratee : S , source : S [ ] , target : D ) : any ;
31
+ export interface ActionFunction < D , S , R > {
32
+ ( iteratee : S , source : S [ ] , target : D ) : R ;
36
33
}
37
34
/**
38
35
* A String path that indicates where to find the property in the source input
@@ -100,7 +97,7 @@ export type ActionAggregator = string[];
100
97
*```
101
98
*
102
99
*/
103
- export type ActionSelector = { path : string | string [ ] ; fn : ( fieldValue : any , items : any [ ] ) => any } ;
100
+ export type ActionSelector < Source , R > = { path : string | string [ ] ; fn : ( fieldValue : any , items : Source [ ] ) => R } ;
104
101
105
102
/**
106
103
* A structure-preserving object from a source data towards a target data.
@@ -134,23 +131,25 @@ export type ActionSelector = { path: string | string[]; fn: (fieldValue: any, it
134
131
* ```
135
132
*/
136
133
137
- export type StrictSchema < Target = { } , Source = any > = {
134
+ export type StrictSchema < Target = any , Source = any > = {
138
135
/** `destinationProperty` is the name of the property of the target object you want to produce */
139
136
[ destinationProperty in keyof Target ] :
140
137
| ActionString < Source >
141
- | ActionFunction < Target , Source >
138
+ | ActionFunction < Target , Source , Target [ destinationProperty ] >
142
139
| ActionAggregator
143
- | ActionSelector
140
+ | ActionSelector < Source , Target [ destinationProperty ] >
144
141
} ;
145
- export type Schema < Target = { } , Source = any > = {
142
+ export type Schema < Target = any , Source = any > = {
146
143
/** `destinationProperty` is the name of the property of the target object you want to produce */
147
144
[ destinationProperty in keyof Target ] ?:
148
145
| ActionString < Source >
149
- | ActionFunction < Target , Source >
146
+ | ActionFunction < Target , Source , Target [ destinationProperty ] >
150
147
| ActionAggregator
151
- | ActionSelector
148
+ | ActionSelector < Source , Target [ destinationProperty ] >
152
149
} ;
153
-
150
+ export function isActionSelector < S , R > ( value : any ) : value is ActionSelector < S , R > {
151
+ return isObject ( value ) ;
152
+ }
154
153
/**
155
154
* Low Level transformer function.
156
155
* Take a plain object as input and transform its values using a specified schema.
@@ -218,11 +217,6 @@ interface Constructable<T> {
218
217
new ( ...args : any [ ] ) : T ;
219
218
}
220
219
221
- export interface Mapper < Target > {
222
- < Source > ( source : Source [ ] ) : Target [ ] ;
223
- < Source > ( source : Source ) : Target ;
224
- }
225
-
226
220
function transformItems < T , TSchema extends Schema < T > > ( schema : TSchema ) : Mapper < { [ P in keyof TSchema ] : any } > ;
227
221
function transformItems < T , TSchema extends Schema < T > > (
228
222
schema : TSchema ,
@@ -266,6 +260,15 @@ function getSchemaForType<T>(type: Constructable<T>, baseSchema: Schema<T>): Sch
266
260
return finalSchema ;
267
261
}
268
262
263
+ type SourceFromSchema < T > = T extends StrictSchema < unknown , infer U > | Schema < unknown , infer U > ? U : never ;
264
+ type DestinationFromSchema < T > = T extends StrictSchema < infer U > | Schema < infer U > ? U : never ;
265
+
266
+ type ResultItem < TSchema extends Schema > = { [ P in keyof TSchema ] : DestinationFromSchema < TSchema > [ P ] } ;
267
+ export interface Mapper < TSchema extends Schema | StrictSchema , TResult = ResultItem < TSchema > > {
268
+ ( data : Partial < SourceFromSchema < TSchema > > [ ] ) : TResult [ ] ;
269
+ ( data : Partial < SourceFromSchema < TSchema > > ) : TResult ;
270
+ }
271
+
269
272
/**
270
273
* Currying function that either outputs a mapping function or the transformed data.
271
274
*
@@ -288,28 +291,32 @@ function getSchemaForType<T>(type: Constructable<T>, baseSchema: Schema<T>): Sch
288
291
* @param { } type
289
292
*
290
293
*/
291
- export function morphism < TSchema extends Schema < { } , Source > , Source > (
294
+ export function morphism < TSchema extends Schema , Source extends object > (
292
295
schema : TSchema ,
293
- items : Source
294
- ) : Source extends any [ ] ? { [ P in keyof TSchema ] : any } [ ] : { [ P in keyof TSchema ] : any } ;
295
- // morphism({},{}) => {}
296
- // morphism({},[]) => Target[]
296
+ data : Source
297
+ ) : Source extends ( infer _C ) [ ] ? ResultItem < TSchema > [ ] : ResultItem < TSchema > ;
297
298
298
- export function morphism < TSchema extends Schema < any > > ( schema : TSchema ) : Mapper < { [ P in keyof TSchema ] : any } > ; // morphism(TSchema) => mapper(S[]) => (keyof TSchema)[]
299
- export function morphism < Target > ( schema : Schema < Target > ) : Mapper < Target > ; // morphism<ITarget>({}) => Mapper<ITarget> => ITarget
300
- export function morphism < Target , Source > (
301
- schema : Schema < Target > ,
299
+ // morphism({}) => mapper(S) => T
300
+ export function morphism < TSchema extends Schema > ( schema : TSchema ) : Mapper < TSchema > ;
301
+
302
+ // morphism({}, null, T) => mapper(S) => T
303
+ export function morphism < TSchema extends Schema , TDestination > (
304
+ schema : TSchema ,
302
305
items : null ,
303
- type : Constructable < Target >
304
- ) : Mapper < Target > ; // morphism({}, null, T) => mapper(S) => T
305
- export function morphism < Target , Source > (
306
- schema : Schema < Target > ,
307
- items : Source [ ] ,
308
- type : Constructable < Target >
309
- ) : Target [ ] ; // morphism({}, [], T) => T[]
310
- export function morphism < Target , Source > ( schema : Schema < Target > , items : Source , type : Constructable < Target > ) : Target ; // morphism({}, {}, T) => T
306
+ type : Constructable < TDestination >
307
+ ) : Mapper < TSchema , TDestination > ;
311
308
312
- export function morphism < Target , Source > ( schema : Schema < Target > , items ?: Source , type ?: Constructable < Target > ) {
309
+ // morphism({}, {}, T) => T
310
+ export function morphism < TSchema extends Schema , Target > (
311
+ schema : TSchema ,
312
+ items : SourceFromSchema < TSchema > ,
313
+ type : Constructable < Target >
314
+ ) : Target ;
315
+ export function morphism < Target , Source , TSchema extends Schema < Target , Source > > (
316
+ schema : TSchema ,
317
+ items ?: SourceFromSchema < TSchema > ,
318
+ type ?: Constructable < Target >
319
+ ) {
313
320
if ( items === undefined && type === undefined ) {
314
321
return transformItems ( schema ) ;
315
322
} else if ( schema && items && type ) {
@@ -336,15 +343,15 @@ export interface IMorphismRegistry {
336
343
* @param schema Structure-preserving object from a source data towards a target data.
337
344
*
338
345
*/
339
- register < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema ?: TSchema ) : Mapper < Target > ;
346
+ register < Target , TSchema > ( type : Constructable < Target > , schema ?: TSchema ) : Mapper < TSchema , Target > ;
340
347
/**
341
348
* Transform any input in the specified Class
342
349
*
343
350
* @param {Type } type Class Type of the ouput Data
344
351
* @param {Object } data Input data to transform
345
352
*
346
353
*/
347
- map < Target > ( type : Target ) : Mapper < Target > ;
354
+ map < Target > ( type : Target ) : Mapper < Schema , Target > ;
348
355
map < Target , Source > ( type : Constructable < Target > , data : Source [ ] ) : Target [ ] ;
349
356
map < Target , Source > ( type : Constructable < Target > , data : Source ) : Target ;
350
357
/**
@@ -353,15 +360,15 @@ export interface IMorphismRegistry {
353
360
* @param {Type } type Class Type of the ouput Data
354
361
*
355
362
*/
356
- getMapper < Target > ( type : Constructable < Target > ) : Mapper < Target > ;
363
+ getMapper < Target > ( type : Constructable < Target > ) : Mapper < Schema , Target > ;
357
364
/**
358
365
* Set a schema for a specific Class Type
359
366
*
360
367
* @param {Type } type Class Type of the ouput Data
361
368
* @param {Schema } schema Class Type of the ouput Data
362
369
*
363
370
*/
364
- setMapper < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema : TSchema ) : Mapper < Target > ;
371
+ setMapper < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema : TSchema ) : Mapper < any , Target > ;
365
372
/**
366
373
* Delete a registered schema associated to a Class
367
374
*
@@ -405,7 +412,7 @@ export class MorphismRegistry implements IMorphismRegistry {
405
412
* @param schema Structure-preserving object from a source data towards a target data.
406
413
*
407
414
*/
408
- register < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema ?: TSchema ) {
415
+ register < Target , TSchema > ( type : Constructable < Target > , schema ?: TSchema ) {
409
416
if ( ! type && ! schema ) {
410
417
throw new Error ( 'type paramater is required when register a mapping' ) ;
411
418
} else if ( this . exists ( type ) ) {
0 commit comments