<commit_before>export interface IClassWithArg<TContainer, TInstance> {
    new(arg: TContainer): TInstance;
}

export interface IClassWithoutArgs<TInstance> {
    new(): TInstance;
}

export type IComponentFunction<TContainer, TInstance> = (container: TContainer) => TInstance;

export type IComponentClassOrFunction<TContainer, TInstance> =
    | IClassWithArg<TContainer, TInstance>
    | IClassWithoutArgs<TInstance>
    | IComponentFunction<TContainer, TInstance>
;

/**
 * Adds a member component to a parent container.
 *
 * @param componentFunction   Class or function that creates the component.
 */
export const component = <TContainer extends {}, TInstance>(componentFunction: IComponentClassOrFunction<TContainer, TInstance>) =>
    (parentPrototype: TContainer, memberName: string) => {
        Object.defineProperty(parentPrototype, memberName, {
            configurable: true,
            get(this: TContainer): TInstance {
                const value: TInstance = new (componentFunction as IClassWithArg<TContainer, TInstance>)(this);

                Object.defineProperty(this, memberName, {
                    configurable: true,
                    get: () => value,
                });

                return value;
            },
        });
    };
<commit_msg>Fixed tslint callable-types complaints<commit_after>export type IClassWithArg<TContainer, TInstance> = new(arg: TContainer) => TInstance;

export type IClassWithoutArgs<TInstance> = new() => TInstance;

export type IComponentFunction<TContainer, TInstance> = (container: TContainer) => TInstance;

export type IComponentClassOrFunction<TContainer, TInstance> =
    | IClassWithArg<TContainer, TInstance>
    | IClassWithoutArgs<TInstance>
    | IComponentFunction<TContainer, TInstance>
;

/**
 * Adds a member component to a parent container.
 *
 * @param componentFunction   Class or function that creates the component.
 */
export const component = <TContainer extends {}, TInstance>(componentFunction: IComponentClassOrFunction<TContainer, TInstance>) =>
    (parentPrototype: TContainer, memberName: string) => {
        Object.defineProperty(parentPrototype, memberName, {
            configurable: true,
            get(this: TContainer): TInstance {
                const value: TInstance = new (componentFunction as IClassWithArg<TContainer, TInstance>)(this);

                Object.defineProperty(this, memberName, {
                    configurable: true,
                    get: () => value,
                });

                return value;
            },
        });
    };

{'fraction_non_alphanumeric': 0.09817617384555685, 'fraction_numerical': 0.0, 'mean_word_length': 3.1380417335473516, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2336123', 'n_tokens_mistral': 669, 'n_tokens_neox': 656, 'n_words': 163}