Skip to content

Instantly share code, notes, and snippets.

@donpark
Last active March 3, 2020 20:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donpark/9bdef394bc4f5e1e26ee9123116a93e6 to your computer and use it in GitHub Desktop.
Save donpark/9bdef394bc4f5e1e26ee9123116a93e6 to your computer and use it in GitHub Desktop.
Neat deep merge using TypeScript generics
import { mergeObjects } from "./merge";
const defaultOptions = {
userMedia: {
audio: true,
video: false,
channelCount: 1,
autoGainControl: true,
echoCancellation: true,
noiseSuppression: true
},
mediaRecorder: {
mimeType: 'audio/webm; codecs="opus"',
audioBitsPerSecond: 24 * 1024,
},
timeslice: 10,
blob: {
type: "audio/webm"
},
enableVoiceFeedback: true
};
const overridenOptions = mergeObjects(defaultOptions, {
mediaRecorder: {
audioBitsPerSecond: 96 * 1024,
},
});
// Type-safe object merge implementation from https://spin.atomicobject.com/2018/05/14/type-safe-object-merging-2-8/
// Uses TypeScript's built-in utility types (See https://www.typescriptlang.org/docs/handbook/utility-types.html)
type Defined<T> = T extends undefined ? never : T;
type MergedProperties<U, T> = { [K in keyof T & keyof U]: undefined extends T[K] ? Defined<T[K] | U[K]> : T[K] };
type MinusKeys<T, U> = Pick<T, Exclude<keyof T, keyof U>>
export const mergeObjects = <T extends object, U extends object>(t: T, u: U) => ({
...(t as object),
...(u as object)
} as MinusKeys<T, U> & MinusKeys<U, T> & MergedProperties<U, T>);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment