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,35 @@ 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 SourceFromSchema < TSchema > > (
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 any [ ] ? 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
+ export function morphism < TSchema extends Schema , Source extends SourceFromSchema < TSchema > > (
300
+ schema : TSchema ,
301
+ data : Source [ ]
302
+ ) : ResultItem < TSchema > [ ] ;
303
+
304
+ export function morphism < TSchema extends Schema > ( schema : TSchema ) : Mapper < TSchema > ; // morphism({}) => mapper(S) => T
305
+
306
+ export function morphism < TSchema extends Schema , TDestination > (
307
+ schema : TSchema ,
302
308
items : null ,
309
+ type : Constructable < TDestination >
310
+ ) : Mapper < TSchema , TDestination > ; // morphism({}, null, T) => mapper(S) => T
311
+
312
+ export function morphism < TSchema extends Schema , Target > (
313
+ schema : TSchema ,
314
+ items : SourceFromSchema < TSchema > ,
303
315
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
316
+ ) : Target ; // morphism({}, {}, T) => T
311
317
312
- export function morphism < Target , Source > ( schema : Schema < Target > , items ?: Source , type ?: Constructable < Target > ) {
318
+ export function morphism < Target , Source , TSchema extends Schema < Target , Source > > (
319
+ schema : TSchema ,
320
+ items ?: SourceFromSchema < TSchema > ,
321
+ type ?: Constructable < Target >
322
+ ) : any {
313
323
if ( items === undefined && type === undefined ) {
314
324
return transformItems ( schema ) ;
315
325
} else if ( schema && items && type ) {
@@ -336,15 +346,15 @@ export interface IMorphismRegistry {
336
346
* @param schema Structure-preserving object from a source data towards a target data.
337
347
*
338
348
*/
339
- register < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema ?: TSchema ) : Mapper < Target > ;
349
+ register < Target , TSchema > ( type : Constructable < Target > , schema ?: TSchema ) : Mapper < TSchema , Target > ;
340
350
/**
341
351
* Transform any input in the specified Class
342
352
*
343
353
* @param {Type } type Class Type of the ouput Data
344
354
* @param {Object } data Input data to transform
345
355
*
346
356
*/
347
- map < Target > ( type : Target ) : Mapper < Target > ;
357
+ map < Target > ( type : Target ) : Mapper < Schema , Target > ;
348
358
map < Target , Source > ( type : Constructable < Target > , data : Source [ ] ) : Target [ ] ;
349
359
map < Target , Source > ( type : Constructable < Target > , data : Source ) : Target ;
350
360
/**
@@ -353,15 +363,15 @@ export interface IMorphismRegistry {
353
363
* @param {Type } type Class Type of the ouput Data
354
364
*
355
365
*/
356
- getMapper < Target > ( type : Constructable < Target > ) : Mapper < Target > ;
366
+ getMapper < Target > ( type : Constructable < Target > ) : Mapper < Schema , Target > ;
357
367
/**
358
368
* Set a schema for a specific Class Type
359
369
*
360
370
* @param {Type } type Class Type of the ouput Data
361
371
* @param {Schema } schema Class Type of the ouput Data
362
372
*
363
373
*/
364
- setMapper < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema : TSchema ) : Mapper < Target > ;
374
+ setMapper < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema : TSchema ) : Mapper < any , Target > ;
365
375
/**
366
376
* Delete a registered schema associated to a Class
367
377
*
@@ -405,7 +415,7 @@ export class MorphismRegistry implements IMorphismRegistry {
405
415
* @param schema Structure-preserving object from a source data towards a target data.
406
416
*
407
417
*/
408
- register < Target , TSchema extends Schema < Target > > ( type : Constructable < Target > , schema ?: TSchema ) {
418
+ register < Target , TSchema > ( type : Constructable < Target > , schema ?: TSchema ) {
409
419
if ( ! type && ! schema ) {
410
420
throw new Error ( 'type paramater is required when register a mapping' ) ;
411
421
} else if ( this . exists ( type ) ) {
0 commit comments