Концептуально, вы должны link
два параметра (имя операции и объект). Для этого вы можете использовать несколько интерфейсов, каждый из которых определяет полный объект с именем операции и входным значением. Это можно использовать в качестве типа «объединение», где клавиша operation
будет действовать как дискриминатор, сообщая механизму TS, какое значение вы используете для операции:
type AInput = {
operation: 'create',
obj: A;
}
type BInput = {
operation: 'edit',
obj: B;
}
const action: AInput | BInput = { operation: 'edit', obj: { bar: 'abc' } };
(new AddressRepository())[action.operation](action.obj);
Это не будет ошибка выброса ( см. на детской площадке ), поскольку TS теперь знает, что action.obj
строго связано с action.operation
.
Более того, вы можете автоматически извлекать (если хотите) эти введите непосредственно из класса, например:
type AddressRepositoryInput = {
[K in keyof AddressRepository]: AddressRepository[K] extends (obj: infer TObj) => infer R
? { type: K, obj: TObj }
: never;
}[keyof AddressRepository];
, затем вы можете просто набрать:
const action: AddressRepositoryInput = { type: 'edit', obj: { ... } };
, и он подтвердит ваш ввод.