如何解决具有通用方法和继承的Typescript工厂,无法将错误分配给type
为什么打字稿编译器不接受以下代码? (我试图使代码不言自明。)
我遇到以下错误Type 'Dog' is not assignable to type 'K'
和Type 'Drone' is not assignable to type 'K'
。
我知道我可以通过使用联合类型Dog | Drone
作为工厂的输出类型来使用变通办法,但这意味着为创建的每个新对象更新签名。我想知道是否有一种“通用”的声明方式。
interface executeFn<I> {
(param: I): string
}
interface Robot<I> {
execute: executeFn<I>
}
interface BaseOrder {
name: string
}
interface DogOrder extends BaseOrder {
action: string
}
interface DroneOrder extends BaseOrder {
destination: string
}
class Dog implements Robot<DogOrder> {
execute(order: DogOrder): string {
return 'The action is ' + order.action
}
}
class Drone implements Robot<DroneOrder> {
execute(order: DroneOrder): string {
return 'The destination is ' + order.destination
}
}
function robotFactory<T extends BaseOrder,K extends Robot<BaseOrder>>(
param: T
): K {
if (((param as unknown) as DogOrder).action) {
return new Dog()
}
return new Drone()
}
请注意,我还尝试更改了通用方法签名,但这不能解决pb。
interface executeFn<I> {
<T extends I>(param: T): string
}
解决方法
编译器会正确警告您K可能并不总是Dog或Drone的事实。
class DroneAdversary implements Robot<DroneOrder> {
execute(order: DroneOrder): string {
return 'The destination is ' + order.destination
}
}
const adversary = robotFactory<DroneOrder,DroneAdversary>({
name: 'aaa',destination: 'dest'
}); // adversary type is DroneAdversary
我会超载:
function isDogOrder(order: BaseOrder): order is DogOrder {
return !!((order as DogOrder).action);
}
function robotFactoryOverload(order: DogOrder): Dog
function robotFactoryOverload(order: DroneOrder): Drone
function robotFactoryOverload(order: DogOrder | DroneOrder): Dog | Drone {
if (isDogOrder(order)) {
return new Dog()
} else {
return new Drone()
}
}
const x = robotFactoryOverload({
name: 'aaa',destination: 'sasas'
});
,
要进一步扩展Lesiak的答案,如果您定义了Robot
类型的并集,则可以自动定义所有重载,如果您有很多重载,则可以提供帮助。
type AnyRobot = Dog | Drone
type RobotForOrder<O extends BaseOrder,R = AnyRobot> = R extends Robot<O> ? R : never
function robotFactory<T extends BaseOrder> (order: T): RobotForOrder<T>
function robotFactory<T extends BaseOrder> (order: T): AnyRobot {
if (isDogOrder(order)) {
return new Dog()
}
return new Drone()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。