23

Let's say I have a type like this:

type User = {
  uid: string,
  displayName?: string,
  bestFriend?: string,
}

Is it possible to extract the optional properties from my User type using a mapped type of some kind? I'm looking for how to define the OptioanlProperties<T> type below.

type OptionalUserProperties = OptionalProperties<User>
// type OptionalUserProperties = "displayName" | "bestFriend"

My use-case is to compute an UpdateOf<User> type that permits specific "operation" values, like DeleteProperty to be assigned to keys that are optional in the base type.

export type UpdateOf<T> =
  // optional fields may be their own type, or the special DeleteProperty type.
  { [P in OptionalProperties<T>]?: T[P] | DeleteProperty } &
  // required fields may be changed, but cannot be deleted.
  { [P in Diff<keyof T, OptionalProperties<T>>]?: T[P] }
0

1 Answer 1

49

Yes:

type OptionalPropertyOf<T extends object> = Exclude<{
  [K in keyof T]: T extends Record<K, T[K]>
    ? never
    : K
}[keyof T], undefined>
Sign up to request clarification or add additional context in comments.

3 Comments

This is much more concise than the solution in the linked duplicate question. Thank you.
Indeed this solution feels better as well.
This is amazing what one can do with TypeScript! I needed this to improve my ModifyDeep to allow changing of property optionality of an existing type.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.