Skip to content

Instantly share code, notes, and snippets.

@TerenceZ
Last active April 30, 2019 02:04
Show Gist options
  • Select an option

  • Save TerenceZ/85c5879b891fc0911b5f78cbf32c3005 to your computer and use it in GitHub Desktop.

Select an option

Save TerenceZ/85c5879b891fc0911b5f78cbf32c3005 to your computer and use it in GitHub Desktop.
make some record items optional if match
type Optional<T> = { [K in keyof T]?: T[K] }
type UnionToIntersection<U> = (U extends any
? (k: U) => void
: never) extends ((k: infer I) => void)
? I
: never
type OptionalIfMatch<T, C, R> = T extends C ? Optional<R> : R
type OptionalIfNotMatch<T, C, R> = T extends C ? R : Optional<R>
type MakeOneRecordItemOptionalIfMatch<
T,
C,
K extends keyof T
> = OptionalIfMatch<T[K], C, Pick<T, Extract<K, keyof T>>>
type MakeOneRecordItemOptionalIfNotMatch<
T,
C,
K extends keyof T
> = OptionalIfNotMatch<T[K], C, Pick<T, Extract<K, keyof T>>>
// What we've done is to pick each item to test and then return one record with only one item.
// finally union them and transform the union to intersection.
type MakeSomeRecordItemsOptionalIfMatch<T, C> = UnionToIntersection<
{ [K in keyof T]: MakeOneRecordItemOptionalIfMatch<T, C, K> }[keyof T]
>
type MakeSomeRecordItemsOptionalIfNotMatch<T, C> = UnionToIntersection<
{ [K in keyof T]: MakeOneRecordItemOptionalIfNotMatch<T, C, K> }[keyof T]
>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment