Я пытаюсь создать метод Factory в TypeScript, который создает класс (экземпляр) с несколькими примененными миксинами на основе одного из аргументов метода Factory.
Это код, переносимый из простого JavaScript. Функционально он работает нормально, просто TypeScript не «распознает» происходящие динамические вещи, поэтому он не знает returnType фабричного метода.
Это код, который у меня есть на данный момент, и япытаюсь заставить TypeScript каким-то образом узнать returnType метода ServiceFactory, который, по крайней мере, всегда BaseModel, но в зависимости от значения параметра операций, также дополнен такими интерфейсами, как ICreatable.
const OPERATIONS = Object.freeze({
/** Only HTTP GET support (methods: all and show) */
DEFAULT: 0,
/** HTTP POST (method: create */
CREATE: 1,
/** HTTP PATCH (method: update */
UPDATE: 2,
/** both HTTP POST & PATCH (methods: create & update */
CREATE_AND_UPDATE: 3,
/** HTTP PUT (method: replace */
REPLACEABLE: 4,
/** HTTP DELETE (method: delete */
DELETE: 8,
/** HTTP GET, POST, PUT, PATCH & DELETE (methods: all, show, create, replace, update & delete) */
ALL: 15,
});
type Constructor<T = {}> = new (...args: any[]) => T;
export interface ICreatable {
create(requestContext:object, body: object, options:object): Promise<object>
}
export class BaseModel {}
export const Creatable = <T extends Constructor<BaseModel>>(Sup: T) => class extends Sup implements ICreatable {
async create(): Promise<object> {
return ...;
}
};
export function ServiceFactory(name: string, operations = OPERATIONS.DEFAULT): BaseModel {
let Clazz = { [name]: class extends BaseModel {} }[name]; // https://stackoverflow.com/questions/33605775/es6-dynamic-class-names/33611096
//if (operations & OPERATIONS.UPDATE) {
// Clazz = Updatable(Clazz);
//}
if (operations & OPERATIONS.CREATE) {
Clazz = Creatable(Clazz);
}
//if (operations & OPERATIONS.DELETE) {
// Clazz = Deletable(Clazz);
//}
//if (operations & OPERATIONS.REPLACEABLE) {
// Clazz = Replaceable(Clazz);
//}
return new Clazz();
}
Когда яЧтобы вызвать приведенный ниже код, TypeScript должен знать, что у someNameClassInstance есть метод с именем 'create'
const someNameClassInstance = ServiceFactory('someName', OPERATIONS.CREATE)
someNameClassInstance. //auto complete should yield 'create'
``