我正在尝试将2个单独的Typescript方法合并为一个具有相同名称getDevice
的方法。如果没有设备,第一个函数只需要一个数字即可返回Device
或null
:
protected getDevice(deviceId: number): Device | null {
const device = this.devicesService.getDevice(deviceId);
if (device == null)
console.warn(`Failed to get the device #${deviceId}.`);
return device;
}
第二个函数接受2个参数。第一个是数字(例如上一个函数)或Device
(上一个函数的结果):
protected getDeviceAs<T extends DeviceType>(
deviceOrId: Device | number,
deviceType: (new (device: Device) => T),
): T | null {
const device = typeof deviceOrId === 'number'
? this.devicesService.getDevice(deviceOrId)
: deviceOrId as Device;
if (device == null) {
console.warn(`Failed to get the device #${deviceOrId}.`);
return null;
}
return new deviceType(device);
}
结合两种方法的结果将是这样的:
protected getDevice<T extends DeviceType>(
deviceOrId: Device | number,
deviceType: (new (device: Device) => T) | null = null,
): Device | T | null {
let device: Device | null = null;
// In case deviceOrId is a number
if (typeof deviceOrId === 'number') {
device = this.devicesService.getDevice(deviceOrId);
if (device == null) {
console.warn(`Failed to get the device #${deviceOrId}.`);
return null;
}
if (deviceType == null) return device;
}
// getDeviceAs functionality
return new deviceType(device);
}
问题是我无法正确输入整个功能:
deviceOrId
参数类型:
deviceOrId
是Device
,则肯定结果必须是T | null
deviceOrId
是number
,则它可能是Device | T | null
deviceOrId
取决于deviceType
参数:
deviceType
是null
,则deviceOrId
的类型必须为number
,返回类型为Device | null
deviceType
是(new (device: Device) => T)
,则返回类型必须为T | null
在打字稿中甚至有可能吗?如果是,怎么办?也许有一些函数重载技巧?
答案 0 :(得分:1)
有一个简单的解决方案。您可以在打字稿(documentation)中重载函数。首先,您声明函数签名。如果出现这个问题,它将是:
protected getDevice(deviceId: number): Device | null;
protected getDevice<T extends DeviceType>(
deviceOrId: Device | number,
deviceType: (new (device: Device) => T),
): T | null;
然后,编写将处理逻辑的函数实现。该实现功能签名不会被视为另一个重载。完整代码:
// Overload 1:
protected getDevice(deviceId: number): Device | null;
// Overload 2:
protected getDevice<T extends DeviceType>(
deviceOrId: Device | number,
deviceType: (new (device: Device) => T),
): T | null;
// Implementation:
protected getDevice<T extends DeviceType>(
deviceOrId: Device | number,
deviceType: (new (device: Device) => T) | null = null,
): Device | T | null {
let device: Device | null = null;
if (typeof deviceOrId === 'number') {
device = this.devicesService.getDevice(deviceOrId);
if (device == null) {
console.warn(`Failed to get the device #${deviceOrId}.`);
return null;
}
if (deviceType == null) return device;
}
return new deviceType(device);
}