Skip to content

Instantly share code, notes, and snippets.

@yarastqt
Created November 12, 2018 08:15
Show Gist options
  • Save yarastqt/35be2198b9bc7980a8e9ed2910703f88 to your computer and use it in GitHub Desktop.
Save yarastqt/35be2198b9bc7980a8e9ed2910703f88 to your computer and use it in GitHub Desktop.
withBemMod<P, T>(blockName: string, mod: NoStrictEntityMods, cb?: ModBody<P>): (WrappedComponent: EnhancedComponentType<{}, {}, T>) => (props: P) => JSX.Element;
type EnhancedComponentType<T = {}, S = any, V = any> =
& React.ComponentType<T>
& Nominal<V>;
type GetKey<T> = T extends EnhancedComponentType<any, any, infer V> ? V : never;
type GetProps<T> = T extends React.ComponentType<infer V> ? V : never;
export function composeM<
T1, T extends (React.ComponentType | EnhancedComponentType),
V1, V extends (React.ComponentType | EnhancedComponentType),
K1, K extends (React.ComponentType | EnhancedComponentType),
>(
a: (component: T) => React.ComponentType<T1>,
b: (component: V) => React.ComponentType<V1>,
c: (component: K) => React.ComponentType<K1>,
) {
type Val11 = T1 extends { [U in GetKey<T>]?: string } ? T1[GetKey<T>] : never;
type Val12 = V1 extends { [U in GetKey<T>]?: string } ? V1[GetKey<T>] : never;
type Val13 = K1 extends { [U in GetKey<T>]?: string } ? K1[GetKey<T>] : never;
type Val21 = T1 extends { [U in GetKey<V>]?: string } ? T1[GetKey<V>] : never;
type Val22 = V1 extends { [U in GetKey<V>]?: string } ? V1[GetKey<V>] : never;
type Val23 = K1 extends { [U in GetKey<V>]?: string } ? K1[GetKey<V>] : never;
type Val31 = T1 extends { [U in GetKey<K>]?: string } ? T1[GetKey<K>] : never;
type Val32 = V1 extends { [U in GetKey<K>]?: string } ? V1[GetKey<K>] : never;
type Val33 = K1 extends { [U in GetKey<K>]?: string } ? K1[GetKey<K>] : never;
type R1 = GetKey<T> extends never ? GetProps<T> : { [U in GetKey<T>]?: Val11 | Val12 | Val13; };
type R2 = GetKey<V> extends never ? GetProps<V> : { [U in GetKey<V>]?: Val21 | Val22 | Val23; };
type R3 = GetKey<K> extends never ? GetProps<K> : { [U in GetKey<K>]?: Val31 | Val32 | Val33; };
return function<Q extends React.ComponentType<any>>(component: Q)
: React.ComponentType<
// Свойства компонента
& JSX.LibraryManagedAttributes<Q, GetProps<Q>>
// Свойства модификаторов с объединением значений
& R1 & R2 & R3
// Свойства модификаторов для подсказок, т.к. выше у нас динамически созданные интерфейсы
& (T1 | V1 | K1)
>
{
return null;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment