/** @module maybe-functions.ts */ import { contains } from './array/contains' import { head } from './array/head' import { init } from './array/init' import { last } from './array/last' import { tail } from './array/tail' import { isNullable, isNullyOrNaN } from './check' import { untypedCurry } from './function/untypedCurry' import { WidenType } from './helper-types' import { Just, Maybe, nothing } from './maybe' import { prop, values } from './object' export const safeInit = ( as: A[] ): Maybe => { return isNullable( as ) ? nothing : Maybe.from( init( as ) ) } export const safeHead = ( as: A[] ): Maybe => { return isNullable( as ) ? nothing : Maybe.from( head( as ) ) } export const safeLast = ( as: A[] ): Maybe> => { return isNullable( as ) ? nothing : Maybe.from( last( as ) as WidenType ) } export const safeTail = ( xs: A[] ): Maybe< A[] > => { return isNullable( xs ) ? nothing : Maybe.from( tail( xs ) ) } const _safeProp = untypedCurry( ( str, obj ) => { const result = prop( str )( obj ) return isNullyOrNaN( result ) ? nothing : Just.of( result ) } ) type PossibleKeyValue = A extends keyof O ? keyof O[A] : {} /** * takes an key (or index) and an array or object and returns * a Maybe. A Just containing the value of that object at key * or a Nothing if there is no value at the key index. */ export function safeProp( k: A, obj: O ): Maybe> export function safeProp( k: A ): ( obj: O ) => Maybe> export function safeProp( ...args ) { return _safeProp( ...args ) } /** * takes an index and an array and returns a maybe containing * the value at array's index (or nothing) * @example * safeIndex(2,[1,2,3]) // Just(3) * safeIndex(10,[1,2,3]) // nothing */ const _safeIndex = untypedCurry( ( index, arr ) => Maybe.from( arr[ index ] ) ) export function safeIndexValue( index: I, arr: A & Array<{}> ): Maybe export function safeIndexValue( index: I ): ( arr: A ) => Maybe export function safeIndexValue( ...args ) { return _safeIndex( ...args ) } type StripAllNullValue< A extends object> = { [I in keyof A]: A[I] extends infer U ? U extends undefined | null ? never : U : never } export const maybeAllValues = ( o: O ): Maybe> => Maybe.of( o ) .map( values ) .map( contains ) .chain( ( _contains: ( ( a: any ) => boolean ) ) => ( _contains( null ) || _contains( undefined ) ) ? nothing : Maybe.of( o ), ) as Maybe < StripAllNullValue < O >> // declare function test( a: A ): AllNotNull