Skip to content

Instantly share code, notes, and snippets.

@lordlycastle
Last active July 19, 2021 17:50
Show Gist options
  • Save lordlycastle/dc0569a8b2452b2373d8fa15ee1478ee to your computer and use it in GitHub Desktop.
Save lordlycastle/dc0569a8b2452b2373d8fa15ee1478ee to your computer and use it in GitHub Desktop.
Creates types that allow you to create a map of properties of certain type of an object. This map is then recognised by compiler to be compatible with object's keys.
/**
* Creates a union type with names of all properties of T where S extends T[Key]
*
* @example
* ```ts
* type T = { a: string; b?: string; c: string | undefined; d: string | null; e: number };
* type StringPropertiesFromT = PropertiesOfType<T, string>; // 'a' | 'b' | 'c' | 'd'
* ```
*/
export type PropertiesOfType<T, S> = {
[Key in keyof T]-?: S extends T[Key] ? (T[Key] extends S ? Key : never) : never;
}[keyof T];
/**
* Creates a new union type with names of all properties T where S does not extend T[Key].
* @example
* ```ts
* type T = { a: string; b?: string; c: string | undefined; d: string | null; e: number };
* type StringPropertiesFromT = PropertiesOfType<T, string>; // 'e'
* ```
*/
export type PropertiesNotOfType<T, S> = Exclude<keyof T, PropertiesOfType<T, S>>;
/**
* Creates a new interface type from T with properties that extend S.
*
* @example
* ```ts
* type T = { a: string; b?: string; c: string | undefined; d: string | null; e: number };
* type StringPropertiesFromT = KeysOfType<T, string>; // {a: string, b?: string, c: string | undefined, d: string | null}
* ```
*/
// export type KeysOfType<T, S> = Pick<T, PropertiesOfType<T, S>>;
export type KeysOfType<T, S> = Omit<T, PropertiesNotOfType<T, S>>;
type T = { a: string; b?: string; c: string | undefined; d: string | null; e: number };
type StringPropertiesFromT = PropertiesOfType<T, string | null>; // 'a' | 'b' | 'c' | 'd'
type NotStringPropertiesFromT = PropertiesNotOfType<T, string | null>;
type StringPropertiesFromT = KeysOfType<T, string | undefined>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment