Skip to content

Instantly share code, notes, and snippets.

@gund
Last active January 24, 2019 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gund/15ef53693e92fb9801ca20951db02bc7 to your computer and use it in GitHub Desktop.
Save gund/15ef53693e92fb9801ca20951db02bc7 to your computer and use it in GitHub Desktop.
Easily extend decorator configuration by producing new decorators
type DecoratorFactory<T, D extends Function> = (config: T) => D;
type PropertyDecoratorFactory<T> = DecoratorFactory<T, PropertyDecorator>;
function extendDecoratorConfig<C>(decoratorFactory: PropertyDecoratorFactory<C>) {
return <C_CUSTOM = {}, C_NEW extends C = C>(
configFactory: (config: C & C_CUSTOM) => C_NEW,
) => (userConfig?: C & C_CUSTOM) => decoratorFactory(configFactory(userConfig));
}
function Property(config?: { required?: boolean }): PropertyDecorator {
return () => null;
}
const customProperty = extendDecoratorConfig(Property);
const NotEmptyProperty = customProperty(config => ({
...config,
typeFactory: type => t.refine(type, str => str.length > 0, 'NotEmpty'),
}));
const MinLengthProperty = customProperty<{ length?: number }>(config => ({
...config,
typeFactory: type => t.refine(type, str => str.length > config.length, 'NotEmpty'),
}));
const PotatoDecorator = customProperty(config => ({
...config,
wasRequired: config.required ? 'yes' : 'no',
}));
class A {
@NotEmptyProperty({ })
potatoCount: string;
@MinLengthProperty({ length: 5 })
potatoCount2: string;
@PotatoDecorator({ required: false })
potatoCount3: string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment