我正try 在代码库中键入一个遗留函数,该函数调用某些对象上的方法(并应用错误处理等).下面的部分(玩具)解决方案适用于约束action
类型,但不能给出准确的返回类型(返回any
).
entityGetter
函数应该接受EntityA或EntityB,并且只接受以'get'
开头的可调用键.后一部分工作正常,这告诉我获得正确的返回值必须是可能的;但是我不明白为什么action
在访问entity
时没有正确的类型.
我已经try 为T和A赋值默认值,这似乎不会改变任何东西.
是否有可能在不对entityGetter
函数的(运行时)接口进行任何更改的情况下使其工作?理想情况下,根本不需要更改JS,但允许对函数体进行一些更改.
type TEntityA = {
getA: () => string;
getB: () => string;
setC: (arg0: string) => string;
valD: number;
getE: () => object;
};
type TEntityB = {
getA: () => string;
getB: () => number;
setC: (arg0: string) => string;
valD: string;
};
type TEntities = TEntityA | TEntityB;
// type KeysOfType = https://stackoverflow.com/a/64254114
type TGetterKeys<T extends TEntities> = keyof Pick<T, keyof T & (`get${string}`)>;
type TCallableKeys<T extends TEntities> = KeysOfType<T, () => unknown>;
type TGetters<T extends TEntities> = TGetterKeys<T> & TCallableKeys<T>;
const entityGetter = <
T extends TEntities,
A extends TGetters<T>
>(action: A, entity: T) => entity[action]();
// This expression is not callable. Type 'unknown' has no call signatures.
const entityA = new EntityA();
const entityB = new EntityB();
const AgetA = entityGetter('getA', entityA); // => string
const BgetB = entityGetter('getB', entityB); // => number
const AgetX = entityGetter('getX', entityA);
// Argument of type '"getX"' is not assignable to parameter of type '"getA" | "getB" | "getE"'.