我有以下超类,T应该是API返回的类型
export class Command<T> {
}
这是一个扩展命令的登录命令:
export class LoginCommand extends Command<LoginResult> {
username: string;
password: string;
}
返回对象:
export class LoginResult {
success: boolean;
token: string;
}
调用方法时:
public call<R>(command: model.command.Command<R>): R {
return null as R; // code omitted
}
使用以下参数:
const cmd = new LoginCommand();
const success = this.call(cmd).success;
它会产生错误: [ts]类型“{}”上不存在属性“成功”
问题1 :如何修改方法签名以正确推断来自Command的R作为返回类型?我也尝试了以下语法,结果相同:
public call<T extends Command<R>, R>(command: T): R
问题2 :为什么ask方法接受不扩展Command的参数?传入一个字符串不会产生任何错误。
答案 0 :(得分:1)
最后一个问题是最容易回答的问题,你的Command
基类没有属性或方法,因此任何类型都将在结构上等同于它,包括字符串。
问题的另一部分更难,如果从泛型类型传递派生类型,编译器将不会向下钻取以推断泛型参数。
您可以执行以下操作之一:
向with
班级添加Command
操作
export class Command<T> {
private something: "";
with(fn: (cmd: Command<T>) => T) : T{
return fn(this);
}
}
//Usage:
public call<R>(command: Command<R>): R {
return null as R; // code omitted
}
public doStuff() {
const cmd = new LoginCommand();
const success = cmd.with(this.call).success; // Works
}
向基类添加一个简单的强制转换方法
export class Command<T> {
private something: "";
asCmd(): Command<T> { return this;}
}
public doStuff() {
const cmd = new LoginCommand();
const success = this.call(cmd.asCmd()).success;
}