【发布时间】:2020-06-06 19:22:45
【问题描述】:
我有一个JS函数
const fn = (cb, param) => {
cb(param);
};
打算以两种方式调用(在 TS 中):
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,因此它不需要类型转换。此外,似乎 TS 拒绝推断参数类型,因为IFn 声明了重载。我能做的最好的就是:
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 可以发现实现内部的上述断言冲突?
显然,我对运行时检查不感兴趣。
【问题讨论】:
-
您不使用function overloads 有什么原因吗?就此而言,
const fn: IFn = (cb: any, param?: string) => cb(param);工作正常,世界其他地方只能通过IFn界面看到它,所以any无关紧要。 -
@jonrsharpe 感谢您的来信。我认为问题中具有重载的接口相当于链接下的函数重载,但是在我的风格中我使用 const + 箭头函数,因此在这种情况下不清楚如何使用函数重载。另外,问题是如何在我的函数定义中使用类型检查,因为只使用实际定义签名中的类型,所以没有提供哪些函数重载。
-
我不清楚您在这里遇到了什么问题。 “在我的函数定义中进行类型检查” 对您意味着什么?您如何看待“实际定义签名”?请edit澄清。
-
@jonrsharpe 重写了问题部分
标签: typescript generics typescript-generics