Skip to content

Commit

Permalink
fix: small tweaks to types and formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Rebecca Stevens authored and RebeccaStevens committed Nov 27, 2020
1 parent 6494a33 commit 0c343f2
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/deepmerge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function deepmerge<T1 extends object, T2 extends object, O extend
* @param options Deep merge options.
*/
export function deepmergeAll<
Ts extends readonly [object, ...Array<object>],
Ts extends readonly [object, ...ReadonlyArray<object>],
O extends Options = object
>(objects: [...Ts], options?: O): DeepMergeAll<Ts, ExplicitOptions<O>>

Expand All @@ -38,7 +38,7 @@ export function deepmergeAll<
export function deepmergeAll(objects: ReadonlyArray<object>, options?: Options): object
export function deepmergeAll(objects: ReadonlyArray<object>, options?: Options): object {
if (!Array.isArray(objects)) {
throw new Error(`first argument should be an array`)
throw new TypeError(`first argument should be an array`)
}

return objects.reduce((prev, next) => deepmergeImpl(prev, next, getFullOptions(options)), {})
Expand Down
14 changes: 7 additions & 7 deletions src/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function emptyTarget(value: unknown) {

export function cloneUnlessOtherwiseSpecified<T>(value: T, options: FullOptions): T {
return options.clone !== false && options.isMergeable(value)
? (deepmergeImpl(emptyTarget(value), value, options) as T)
? deepmergeImpl(emptyTarget(value), value, options) as T
: value
}

Expand All @@ -30,7 +30,7 @@ function getKeys(target: object): Array<string> {
function propertyIsOnObject(object: object, property: Property): boolean {
try {
return property in object
} catch (_) {
} catch {
return false
}
}
Expand Down Expand Up @@ -101,17 +101,17 @@ export function deepmergeImpl<T1 extends any, T2 extends any, O extends Options>

if (!sourceAndTargetTypesMatch) {
return cloneUnlessOtherwiseSpecified(source, options) as DeepMerge<T1, T2, ExplicitOptions<O>>
} else if (sourceIsArray) {
}
if (sourceIsArray) {
return options.arrayMerge(
target as Array<unknown>,
source as Array<unknown>,
options,
) as DeepMerge<T1, T2, ExplicitOptions<O>>
} else {
return mergeObject(
}
return mergeObject(
target as Record<Property, unknown>,
source as Record<Property, unknown>,
options,
) as DeepMerge<T1, T2, ExplicitOptions<O>>
}
) as DeepMerge<T1, T2, ExplicitOptions<O>>
}
20 changes: 10 additions & 10 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,32 @@ import type { FlattenAlias, Property } from "./types"
* Deep merge options.
*/
export type Options = Partial<{
arrayMerge?: ArrayMerge
clone?: boolean
customMerge?: ObjectMerge
isMergeable?: IsMergeable
readonly arrayMerge?: ArrayMerge
readonly clone?: boolean
readonly customMerge?: ObjectMerge
readonly isMergeable?: IsMergeable
}>

/**
* Deep merge options with explicit keys.
*/
export type ExplicitOptions<O extends Options = Options> = {
[K in keyof Options]-?: undefined extends O[K] ? never : O[K]
readonly [K in keyof Options]-?: undefined extends O[K] ? never : O[K]
}

/**
* Deep merge options with defaults applied.
*/
export type FullOptions<O extends Options = Options> = FlattenAlias<{
arrayMerge: O[`arrayMerge`] extends undefined
readonly arrayMerge: O[`arrayMerge`] extends undefined
? typeof defaultArrayMerge
: NonNullable<O[`arrayMerge`]>
clone: O[`clone`] extends undefined ? true : NonNullable<O[`clone`]>
customMerge?: O[`customMerge`]
isMergeable: O[`isMergeable`] extends undefined
readonly clone: O[`clone`] extends undefined ? true : NonNullable<O[`clone`]>
readonly customMerge?: O[`customMerge`]
readonly isMergeable: O[`isMergeable`] extends undefined
? typeof defaultIsMergeable
: NonNullable<O[`isMergeable`]>
cloneUnlessOtherwiseSpecified: <T>(value: T, options: FullOptions) => T
readonly cloneUnlessOtherwiseSpecified: <T>(value: T, options: FullOptions) => T
}>

/**
Expand Down
5 changes: 3 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import type { Options } from "./options"
* Deep merge 1 or more types given in an array.
*/
export type DeepMergeAll<
Ts extends readonly [any, ...Array<any>],
Ts extends readonly [any, ...ReadonlyArray<any>],
O extends Options
> = Ts extends readonly [infer T1, ...Array<any>]
> = Ts extends readonly [infer T1, ...ReadonlyArray<any>]
? Ts extends readonly [T1, infer T2, ...infer TRest]
? TRest extends ReadonlyArray<never>
? DeepMerge<T1, T2, O>
Expand Down Expand Up @@ -81,6 +81,7 @@ type DeepMergeObjectPropsCustom<T1, T2, O extends Options> = ReturnType<
*
* Cannot get return type from arrayMerge passing generics.
* TypeScript does not yet support higher order types.
*
* @see https://github.com/Microsoft/TypeScript/issues/1213
*/
type DeepMergeArrays<T1, T2, O extends Options> = IsUndefinedOrNever<O[`arrayMerge`]> extends true
Expand Down
2 changes: 1 addition & 1 deletion test/merge-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import test from "tape"
test(`throw error if first argument is not an array`, (t) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error -- FIXME: Can't use @ts-expect-error due to it failing in tests.
// @ts-ignore Expect a type error when calling the function incorrectly.
t.throws(deepmergeAll.bind(null, { example: true }, { another: `2` }), Error)
t.throws(deepmergeAll.bind(null, { example: true }, { another: `2` }), TypeError)
t.end()
})

Expand Down

0 comments on commit 0c343f2

Please sign in to comment.