我有一个JS函数
const fn = (cb, param) => {
cb(param);
};
在TS中将被称为2种方式:
const cb0 = () => {};
fn(cb0);
const cb1 = (param: string) => { };
fn(cb1, 'str')
fn
的期望通过这种类型正确描述:
interface IFn {
(cb: (param: string) => void, param: string): void;
(cb: () => void): void;
}
fnI(cb0); // ok
// fnI(cb1); // correctly does not compile, callback needs an argument
fnI(cb1, 's'); // ok
因此它检查呼叫者站点的类型。但是,我无法将fn
转换为Typescript,因此不需要类型转换。此外,由于IFn
声明了重载,因此TS似乎拒绝推断参数类型。我能做的最好的是:
const fn: IFn = <IFn>((cb: (param?: string) => void, param?: string) => {
cb(param);
});
问题是,实现签名的限制较少,以下实现显然违反了IFn
的声明,但类型检查程序无法检测到违反。
const fn: IFn = <IFn>((cb: (param?: string) => void, param?: string) => {
cb(param === undefined ? 'some other string' : undefined);
});
所以问题是:
是否可以定义fn
签名或IFn
,以便TypeScript可以在实现内部发现上述断言?
很显然,我对运行时检查不感兴趣。
答案 0 :(得分:0)
尝试一下:
interface IFn {
(cb: (param: string) => void, param: string): void;
(cb: () => void): void;
}
const fn: IFn = (
...args: [(param: string) => void, string] | [() => void]
) => {
switch (args.length) {
case 2: {
const cb = args[0];
const param = args[1];
cb(param);
break;
}
case 1: {
const cb = args[0];
cb();
break;
}
}
};