![](/img/trans.png)
[英]How to overload a function with multiple parameters correctly in typescript?
[英]How to overload function in TypeScript with optional parameters?
我有以下代码部分转换为 TypeScript (来自 JavaScript)。
基本上,如果存在callback
参数,我总是希望 function 本身返回void
。 否则,返回类型Promise<object>
。 在此之前有一个可选参数( settings
)(因此从技术上讲, callback
参数可以作为settings
参数传入,function 的前几行处理该用例)。
出于向后兼容的目的(并保持代码干燥),我不想创建另一个名为savePromise
或saveCallback
并将其分离出来。 我试图弄清楚如何让 TypeScript 足够聪明,以某种方式理解这个逻辑。
type CallbackType<T, E> = (response: T | null, error?: E) => void;
class User {
save(data: string, settings?: object, callback?: CallbackType<object, string>): Promise<object> | void {
if (typeof settings === "function") {
callback = settings;
settings = undefined;
}
if (callback) {
setTimeout(() => {
callback({"id": 1, "settings": settings});
}, 1000);
} else {
return new Promise((resolve) => {
setTimeout(() => {
resolve({"id": 1, "settings": settings});
}, 1000);
});
}
}
}
const a = new User().save("Hello World"); // Should be type Promise<object>, should eventually resolve to {"id": 1, "settings": undefined}
const b = new User().save("Hello World", (obj) => {
console.log(obj); // {"id": 1, "settings": undefined}
}); // Should be type void
const c = new User().save("Hello World", {"log": true}); // Should be type Promise<object>, should eventually resolve to {"id": 1, "settings": {"log": true}}
const d = new User().save("Hello World", {"log": true}, (obj) => {
console.log(obj); // {"id": 1, "settings": {"log": true}}
}); // Should be type void
我很确定我想要的类型文件将类似于以下内容。 不确定我在这里是否准确。
save(data: string, settings?: object): Promise<object>;
save(data: string, callback: CallbackType<object, string>): void;
save(data: string, settings: object, callback: CallbackType<object, string>): void;
似乎可以通过执行以下操作来处理作为settings
参数用例传入的callback
参数:
save(data: string, settings?: object | CallbackType<object, string>, callback?: CallbackType<object, string>): Promise<object> | void
但这太混乱了,根据我的经验,TypeScript 似乎不够聪明,无法意识到在 ZC1C425268E68A385D1AB5074FC17 中的前 4 行代码之后settings
将始终是可选的 object 这意味着在调用callback
时,您必须输入强制类型转换,这再次让人感觉非常混乱。
如何使用 TypeScript 实现这一目标?
这是解决方案(进行了一些重构):
type CallbackType<T, E> = (response: T | null, error?: E) => void;
interface ISettings {
log?: boolean;
}
interface ISaveResult {
id: number;
settings: ISettings | undefined;
}
class User {
save(data: string): Promise<ISaveResult>;
save(data: string, settings: ISettings): Promise<ISaveResult>;
save(data: string, callback: CallbackType<ISaveResult, string>): void;
save(data: string, settings: ISettings, callback: CallbackType<ISaveResult, string>): void;
save(data: string, settings?: ISettings | CallbackType<ISaveResult, string>, callback?: CallbackType<ISaveResult, string>): Promise<ISaveResult> | void {
if (typeof settings !== "object" && typeof settings !== "undefined") {
callback = settings;
settings = undefined;
}
const localSettings = settings; // required for closure compatibility
if (callback) {
const localCallback = callback; // required for closure compatibility
setTimeout(() => {
localCallback({ id: 1, "settings": localSettings });
}, 1000);
} else {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ id: 1, "settings": localSettings });
}, 1000);
});
}
}
}
const a = new User().save("Hello World"); // User.save(data: string): Promise<ISaveResult>
const b = new User().save("Hello World", obj => {
console.log(obj); // obj: ISaveResult | null
}); // User.save(data: string, callback: CallbackType<ISaveResult, string>): void
const c = new User().save("Hello World", { "log": true }); // User.save(data: string, settings: ISettings): Promise<ISaveResult>
const d = new User().save("Hello World", { "log": true }, (obj) => {
console.log(obj); // obj: ISaveResult | null
}); // User.save(data: string, settings: ISettings, callback: CallbackType<ISaveResult, string>): void
见码盘
Function
也是Object
,因此 TypeScript 无法隐式区分两者。 通过创建特定的ISettings
接口,您允许 TypeScript 区分设置 object 和回调 function。
最简单的查看方法是查看 TypeScript 输出的错误以及代码流进行时的变量类型,例如( 您的代码):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.