diff --git a/src/interfaces/maybe.interface.ts b/src/interfaces/maybe.interface.ts index 42d8580..1032c6a 100644 --- a/src/interfaces/maybe.interface.ts +++ b/src/interfaces/maybe.interface.ts @@ -7,7 +7,7 @@ export interface IMaybePattern { /** * Function to handle when a value exists. */ - some(val: TIn): TOut + some(val: NonNullable): TOut /** * Function to handle when a value is undefined. @@ -22,12 +22,12 @@ export interface IMaybe extends IMonad { /** * Unwrap a Maybe with a default value */ - valueOr(val: T): T + valueOr(val: NonNullable): NonNullable /** * Unwrap a Maybe with a default computed value */ - valueOrCompute(f: () => T): T + valueOrCompute(f: () => NonNullable): NonNullable /** * Execute functions with side-effects. @@ -42,7 +42,7 @@ export interface IMaybe extends IMonad { /** * Execute a function with side-effects when maybe is a some. */ - tapSome(f: (val: T) => void): void + tapSome(f: (val: NonNullable) => void): void /** * Unwrap and apply MaybePattern functions @@ -52,12 +52,12 @@ export interface IMaybe extends IMonad { /** * Combine multiple maybe */ - map(f: (t: T) => R): IMaybe + map(f: (t: NonNullable) => R): IMaybe /** * Combine multiple maybe */ - flatMap(f: (t: T) => IMaybe): IMaybe + flatMap(f: (t: NonNullable) => IMaybe): IMaybe // tslint:disable-next-line:readonly-array of(x?: T, ...args: any[]): IMaybe diff --git a/src/monads/maybe.ts b/src/monads/maybe.ts index e34ff6c..bde440d 100644 --- a/src/monads/maybe.ts +++ b/src/monads/maybe.ts @@ -3,13 +3,13 @@ import { IMaybe, IMaybePattern } from "../interfaces" export function maybe(value?: T): IMaybe { return { of: (x) => maybe(x), - valueOr: (val: T) => value === null || value === undefined ? val : value, - valueOrCompute: (f: () => T) => value === null || value === undefined ? f() : value, - tap: (obj: Partial>) => value === null || value === undefined ? obj.none && obj.none() : obj.some && obj.some(value), + valueOr: (val: NonNullable) => value === null || value === undefined ? val : value as NonNullable, + valueOrCompute: (f: () => NonNullable) => value === null || value === undefined ? f() : value as NonNullable, + tap: (obj: Partial>) => value === null || value === undefined ? obj.none && obj.none() : obj.some && obj.some(value as NonNullable), tapNone: (f: () => void) => (value === null || value === undefined) && f(), - tapSome: (f: (val: T) => void) => value !== null && value !== undefined && f(value), - match: (pattern: IMaybePattern) => value === null || value === undefined ? pattern.none() : pattern.some(value), - map: (f: (t: T) => R) => value === null || value === undefined ? maybe() : maybe(f(value)), - flatMap: (f: (d: T) => IMaybe) => value === null || value === undefined ? maybe() : f(value) + tapSome: (f: (val: NonNullable) => void) => value !== null && value !== undefined && f(value as NonNullable), + match: (pattern: IMaybePattern) => value === null || value === undefined ? pattern.none() : pattern.some(value as NonNullable), + map: (f: (t: NonNullable) => R) => value === null || value === undefined ? maybe() : maybe(f(value as NonNullable)), + flatMap: (f: (d: NonNullable) => IMaybe) => value === null || value === undefined ? maybe() : f(value as NonNullable) } } \ No newline at end of file diff --git a/test/monads/maybe.spec.ts b/test/monads/maybe.spec.ts index a36bf8b..90de6c8 100644 --- a/test/monads/maybe.spec.ts +++ b/test/monads/maybe.spec.ts @@ -3,35 +3,35 @@ import { maybe } from "../../src" describe('Maybe', () => { describe('when returning a value by default', () => { it('should handle "none" case', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined const maybeAString = maybe(sut).valueOr('default output') expect(maybeAString).toEqual('default output') }) it('should handle "some" case', () => { - const sut: string | undefined = 'actual input' + const sut = 'actual input' as string | undefined const maybeAString = maybe(sut).valueOr('default output') expect(maybeAString).toEqual('actual input') }) it('should handle "some" case when input is null', () => { - const sut: string | undefined | null = null + const sut = null as string | undefined | null const maybeAString = maybe(sut).valueOr('default output') expect(maybeAString).toEqual('default output') }) it('should handle "some" case when input is ""', () => { - const sut: string | undefined | null = '' + const sut = '' as string | undefined | null const maybeAString = maybe(sut).valueOr('fallback') expect(maybeAString).toEqual('') }) it('should handle "some" case when input is 0', () => { - const sut: number | undefined | null = 0 + const sut = 0 as number | undefined | null const maybeAString = maybe(sut).valueOr(10) expect(maybeAString).toEqual(0) @@ -40,7 +40,7 @@ describe('Maybe', () => { describe('when returning a value by computation', () => { it('should handle "none" case', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined const maybeAString = maybe(sut).valueOrCompute(() => 'default output') expect(maybeAString).toEqual('default output') @@ -54,21 +54,21 @@ describe('Maybe', () => { }) it('should handle "some" case when input is null', () => { - const sut: string | undefined = null + const sut = null as string | null const maybeAString = maybe(sut).valueOrCompute(() => 'fallback') expect(maybeAString).toEqual('fallback') }) it('should handle "some" case when input is ""', () => { - const sut: string | undefined = '' + const sut = '' as string | undefined const maybeAString = maybe(sut).valueOrCompute(() => 'fallback') expect(maybeAString).toEqual('') }) it('should handle "some" case when input is 0', () => { - const sut: number | undefined = 0 + const sut = 0 as number | undefined const maybeAString = maybe(sut).valueOrCompute(() => 10) expect(maybeAString).toEqual(0) @@ -77,7 +77,7 @@ describe('Maybe', () => { describe('when returning from a match operation', () => { it('should handle "none" case', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined const maybeAMappedString = maybe(sut) .match({ none: () => 'fallback', @@ -88,7 +88,7 @@ describe('Maybe', () => { }) it('should handle "some" case', () => { - const sut: string | undefined = 'existing value' + const sut = 'existing value' as string | undefined const maybeAMappedString = maybe(sut) .match({ none: () => 'fallback', @@ -102,8 +102,8 @@ describe('Maybe', () => { describe('when performing side-effect operations', () => { it('should handle "none" case', () => { // tslint:disable-next-line:no-let - let sideEffectStore: string - const sut: string | undefined = undefined + let sideEffectStore = '' + const sut = undefined as string | undefined maybe(sut) .tap({ @@ -118,8 +118,8 @@ describe('Maybe', () => { it('should handle "some" case', () => { // tslint:disable-next-line:no-let - let sideEffectStore: string - const sut: string | undefined = 'existing value' + let sideEffectStore = '' + const sut = 'existing value' as string | undefined maybe(sut) .tap({ @@ -139,7 +139,7 @@ describe('Maybe', () => { } it('should handle valid input', () => { - const sut: string | undefined = 'initial input' + const sut = 'initial input' as string | undefined const maybeSomeString = maybe(sut) .map(_str => getUserService('initial input mapped')) @@ -163,7 +163,7 @@ describe('Maybe', () => { }) it('should handle undefined input', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined const maybeSomeString = maybe(sut) .map(_str => getUserService('initial input mapped')) @@ -187,7 +187,7 @@ describe('Maybe', () => { }) it('should handle input of 0', () => { - const sut: number | undefined = 0 + const sut = 0 as number | undefined const maybeSomeString = maybe(sut) .map(_str => getUserService('initial input mapped')) @@ -211,7 +211,7 @@ describe('Maybe', () => { }) it('should handle input of ""', () => { - const sut: string | undefined = '' + const sut = '' as string | undefined const maybeSomeString = maybe(sut) .map(_str => getUserService('initial input mapped')) @@ -237,8 +237,8 @@ describe('Maybe', () => { describe('when flatMapping', () => { it('should handle "none" case', () => { - const sut: string | undefined = undefined - const nsut: number | undefined = undefined + const sut = undefined as string | undefined + const nsut = undefined as number | undefined const maybeSomeNumber = maybe(sut) .flatMap(() => maybe(nsut)) @@ -248,8 +248,8 @@ describe('Maybe', () => { }) it('should handle "some" case', () => { - const sut: string | undefined = 'initial' - const nsut: number | undefined = 20 + const sut = 'initial' as string | undefined + const nsut = 20 as number | undefined const maybeSomeNumber = maybe(sut) .flatMap(() => maybe(nsut)) @@ -261,7 +261,7 @@ describe('Maybe', () => { describe('when getting monadic unit', () => { it('should get value', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined const maybeSomeNumber = maybe(sut) .of('ok') @@ -273,7 +273,7 @@ describe('Maybe', () => { describe('when tapSome', () => { it('should work', () => { - const sut: string | undefined = 'abc' + const sut = 'abc' as string | undefined expect.assertions(1) maybe(sut).tapSome(a => expect(a).toEqual('abc')) @@ -283,7 +283,7 @@ describe('Maybe', () => { describe('when tapNone', () => { it('should work', () => { - const sut: string | undefined = undefined + const sut = undefined as string | undefined expect.assertions(1) maybe(sut).tapNone(() => expect(1).toEqual(1)) diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..ad35aba --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "lib": ["es2015", "dom"], + "isolatedModules": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "noImplicitAny": true, + "noImplicitUseStrict": false, + "noEmitHelpers": false, + "noEmit": true, + "noLib": false, + "noUnusedLocals": true, + "noEmitOnError": true, + "allowSyntheticDefaultImports": false, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "forceConsistentCasingInFileNames": true + } +} \ No newline at end of file