diff --git a/package-lock.json b/package-lock.json index 9797c54..fc32936 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13853,9 +13853,9 @@ "dev": true }, "typescript": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.2.tgz", - "integrity": "sha512-Og2Vn6Mk7JAuWA1hQdDQN/Ekm/SchX80VzLhjKN9ETYrIepBFAd8PkOdOTK2nKt0FCkmMZKBJvQ1dV1gIxPu/A==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", "dev": true }, "undefsafe": { diff --git a/package.json b/package.json index 99dd92f..93c424a 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "typedoc": "^0.15.0", "typedoc-plugin-external-module-name": "^2.0.0", "typedoc-plugin-internal-external": "^2.0.1", - "typescript": "^3.4.2", + "typescript": "3.5.3", "webpack": "4.38.0", "webpack-cli": "^3.3.0" }, diff --git a/src/morphism.ts b/src/morphism.ts index 76bb0fe..2bf44d1 100644 --- a/src/morphism.ts +++ b/src/morphism.ts @@ -72,7 +72,7 @@ function transformItems>(schema: TSchema, type tree = new MorphismSchemaTree(schema); } - function mapper(source: any) { + const mapper: Mapper = (source: any) => { if (!source) { return source; } @@ -96,7 +96,7 @@ function transformItems>(schema: TSchema, type return transformValuesFromObject(object, tree, [object], jsObject); } } - } + }; return mapper; } @@ -148,7 +148,17 @@ function morphism( type: Constructable ): Mapper; // morphism({}, null, T) => mapper(S) => T -function morphism(schema: TSchema, items: SourceFromSchema, type: Constructable): Target; // morphism({}, {}, T) => T +function morphism< + TSchema = Schema, SourceFromSchema>, + Target = never, + Source extends SourceFromSchema = SourceFromSchema +>(schema: TSchema, items: Source, type: Constructable): Target; // morphism({}, {}, T) => T + +function morphism< + TSchema = Schema, SourceFromSchema>, + Target = never, + Source extends SourceFromSchema = SourceFromSchema +>(schema: TSchema, items: Source[], type: Constructable): Target[]; // morphism({}, [], T) => T[] function morphism>( schema: TSchema, diff --git a/src/types.ts b/src/types.ts index 36dca74..7227386 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,8 +37,8 @@ export type StrictSchema = { | ActionString | ActionFunction | ActionAggregator - | ActionSelector - | StrictSchema + | ActionSelector + | StrictSchema; } & { [SCHEMA_OPTIONS_SYMBOL]?: SchemaOptions }; export type Schema = { /** `destinationProperty` is the name of the property of the target object you want to produce */ @@ -46,8 +46,8 @@ export type Schema = { | ActionString | ActionFunction | ActionAggregator - | ActionSelector - | Schema + | ActionSelector + | Schema; } & { [SCHEMA_OPTIONS_SYMBOL]?: SchemaOptions }; export type Actions = ActionFunction | ActionAggregator | ActionString | ActionSelector; @@ -172,6 +172,6 @@ export type DestinationFromSchema = T extends StrictSchema | Schema< export type ResultItem = DestinationFromSchema; export interface Mapper> { - (data: SourceFromSchema[]): TResult[]; - (data: SourceFromSchema): TResult; + (data?: SourceFromSchema[] | null): TResult[]; + (data?: SourceFromSchema | null): TResult; } diff --git a/src/typescript.spec.ts b/src/typescript.spec.ts index 2336c30..daccd97 100644 --- a/src/typescript.spec.ts +++ b/src/typescript.spec.ts @@ -161,6 +161,29 @@ describe('Typescript', () => { morphism>({ a: ({ _a }) => _a.toString() }); morphism>({ a: ({ _a }) => _a.toString() }); }); + + it('shoud infer result type from source when a class is provided', () => { + class Source { + constructor(public id: number, public ugly_field: string) {} + } + + class Destination { + constructor(public id: number, public field: string) {} + } + + const source = [new Source(1, 'abc'), new Source(1, 'def')]; + + const schema: StrictSchema = { + id: 'id', + field: 'ugly_field' + }; + const expected = [new Destination(1, 'abc'), new Destination(1, 'def')]; + + const result = morphism(schema, source, Destination); + result.forEach((item, idx) => { + expect(item).toEqual(expected[idx]); + }); + }); }); describe('Morphism Function Type Checking', () => {