Skip to content

Instantly share code, notes, and snippets.

@eddiemoore
Created March 14, 2019 01:36
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eddiemoore/7873191f366675e520e802a9fb2531d8 to your computer and use it in GitHub Desktop.
Save eddiemoore/7873191f366675e520e802a9fb2531d8 to your computer and use it in GitHub Desktop.
Typescript get optional keys from interface
type Undefined<T> = { [P in keyof T]: P extends undefined ? T[P] : never }
type FilterFlags<Base, Condition> = {
[Key in keyof Base]:
Base[Key] extends Condition ? Key : never
};
type AllowedNames<Base, Condition> =
FilterFlags<Base, Condition>[keyof Base];
type SubType<Base, Condition> =
Pick<Base, AllowedNames<Base, Condition>>;
type OptionalKeys<T> = Exclude<keyof T, NonNullable<keyof SubType<Undefined<T>, never>>>
interface Something {
firstName: string
lastName: string
phone?: string
age: number
}
type AllOptionalKeys = OptionalKeys<Something> // "phone"
@gisheri
Copy link

gisheri commented Nov 10, 2021

Could you check if {} extends Pick<T, Key>? Something like this, since undefined is different than optional..

type OptionalKeys<T extends object> = { [P in keyof T]: {} extends Pick<T, P> ? P : never }[keyof T]

@eddiemoore
Copy link
Author

@gisheri yeah that works. A lot simpler. Can't even remember now why I was using this 😂

@zhm-f9203
Copy link

Could you check if {} extends Pick<T, Key>? Something like this, since undefined is different than optional..

type OptionalKeys<T extends object> = { [P in keyof T]: {} extends Pick<T, P> ? P : never }[keyof T]

Can you tell me how this works. {} extends Pick<T, P>
Optional and non-optional attribute types do not behave the same way for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment