Skip to content

Instantly share code, notes, and snippets.

@G-Rath
Last active May 6, 2019 23:43
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 G-Rath/5847f1abaf1876c7e5e8769d1500d74d to your computer and use it in GitHub Desktop.
Save G-Rath/5847f1abaf1876c7e5e8769d1500d74d to your computer and use it in GitHub Desktop.
useful typescript types & files
/*
Lets you extract the properties of an interface that are of a specific type,
such as "this parameter takes the name of any propert of T that maps to a string value".
See "groupObjectsByProperty.ts" for an example.
*/
// region ExtractPropertiesOfType
type FilterFlags<O, T> = { [K in keyof O]: O[K] extends T ? K : never };
type AllowedNames<O, T> = FilterFlags<O, T>[keyof O];
/**
* Extract all properties from `O` that are of type `T`.
*/
export type ExtractPropertiesOfType<O, T> = Pick<O, AllowedNames<O, T>>;
// endregion
/*
Lets you exclude all properties marked as "optional" in an interface,
with "optional" being "marked with ?" (vs "can be undefined").
*/
export type ExcludeOptionalProperties<T> = Pick<T, {
[K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K
}[keyof T]>
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
/*
Shortcut of `Record<string, T>` - I find WebStorm types this better than `Record`.
*/
export type ObjectMap<Type> = {
[k: string]: Type;
}
export interface EventEmitterFuncs<EventEmitterMap> {
on<K extends keyof EventEmitterMap>(event: K, listener: (event: EventEmitterMap[K]) => void): this;
emit<K extends keyof EventEmitterMap>(event: K, eventObj: EventEmitterMap[K], ...args: any[]): boolean;
}
import { ExtractPropertiesOfType } from 'src/definitions';
/**
* Groups an array of objects based on the value of a shared property of type `string`.
*
* @param {Array<T>} objects
* @param {V} property
* @param {string} defaultValue
*
* @return {Record<T[V], Array<T>>}
*
* @template T, V
*/
export default <T extends { [k: string]: any }, V extends keyof ExtractPropertiesOfType<T, PropertyKey | undefined>>(
objects: Array<T>,
property: V,
defaultValue: T[V]
): Record<T[V], Array<T>> => {
const map: Record<PropertyKey, Array<T>> = {};
objects.forEach(obj => {
const value = obj[property] || defaultValue;
if (!map[value]) {
map[value] = [];
}
map[value].push(obj);
});
return map;
};
import { Omit } from 'src/definitions';
/**
* Returns an object containing all the properties in the given `object`,
* except for the ones whose names are included in the `keys` array.
*
* @param {object|T} object
* @param {Array<string|K>} keys
*
* @return {object|{[k in K]: T[k]}}
*
* @template T
* @template K
*/
export default <T, K extends keyof T>(object: T, keys: Array<K>): Omit<T, K> => {
const obj = { ...object };
keys.forEach(key => delete obj[key]);
return obj;
};
/**
* Returns an object containing all the properties in the given `object`,
* except for the ones whose names are not included in the `keys` array.
*
* @param {object|T} object
* @param {Array<string|K>} keys
*
* @return {object|{[k in K]: T[k]}}
*
* @template T
* @template K
*/
export default <T, K extends keyof T = keyof T>(object: T, keys: Array<K & keyof T>): Pick<T, K> => {
const obj = {} as Pick<T, K>;
keys.forEach(key => obj[key] = object[key]);
return obj;
};
export interface Props {
children?: never;
className: string | undefined;
}
const Comp = (props: Props) => {
return <div className={props.className}>Hello World</div>;
};
Comp.defaultProps = {
className: undefined
};
type SuckPropsCombineDefaults<T extends ((...args: any[]) => any) & { defaultProps: any }> = Omit<Parameters<T>[0],
keyof T['defaultProps']> &
Partial<T['defaultProps']>;
type Test = SuckPropsCombineDefaults<typeof Comp>; // correct.
const p: Test = {
className: ''
};
p.className.trim();
/**
* Returns `value` unless `undefined`, in which case returns `unless`.
*
* @param {T?} value
* @param {T} unless
*
* @template T
*/
export default <T>(value: T | undefined, unless: T): T => {
if (value !== undefined) {
return value;
}
return unless;
};
// super useful for express stuff, for put methods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment