在TS中,接口只存在于开发过程中,因此无法在运行时检查接口类型并执行smth。因此,在创建回调方法时,必须以某种方式在接口中包含一个“指示符”,以便将其设置为一些值。此指示器可用于在运行时检查回调类型。TS还提供
User-Defined Type Guards
最终的解决方案是:
interface StringOp {
opType: 'StringOp',
(a: string, b: string): string;
}
interface NumberOp {
opType: 'NumberOp',
(a: number, b: number): number;
}
function isStringOp(op: StringOp | NumberOp): op is StringOp {
return op.opType === 'StringOp';
}
function doThing(callback: StringOp | NumberOp) {
if (isStringOp(callback)) {
callback("a", "b");
} else {
callback(1, 2);
}
}
根据更新后的问题,我添加了另一个示例:
interface TickFunction<T> {
(val: T): void;
}
interface IndexedTickFunction<T> {
(val: T, index: number): void;
}
function isTickFn<T>(fn: TickFunction<T> | IndexedTickFunction<T>): fn is TickFunction<T> {
// in your example the indicator might be the function length
// because it indicates the number of arguments expected by the function
return fn.length === 1;
}
// I guess you also have to pass arguments to this function in order to pass them to your callback methods
function forEachTick<T>(callback: TickFunction<T> | IndexedTickFunction<T>, value: T, index?: number) {
if (isTickFn(callback)) {
callback(value);
} else {
callback(value, index);
}
}
for (let i=0; i<10; i++) {
forEachTick<string>((v: string) => console.log(v), 'some text');
}
for (let i=0; i<10; i++) {
forEachTick<boolean>((v: boolean, index: number) => console.log(v, index), true, i);
}