【问题标题】:How to infer the generic return type that is bound to a generic parameter of a parameterized class in a typescript method?如何推断在打字稿方法中绑定到参数化类的泛型参数的泛型返回类型?
【发布时间】:2018-02-05 00:44:49
【问题描述】:

我有以下超类,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] 类型“{}”上不存在属性“成功”

问题一:如何修改方法签名以正确推断 R from Command 作为返回类型?我还尝试了以下语法,结果相同:

    public call<T extends Command<R>, R>(command: T): R

问题2:为什么 ask 方法接受不扩展 Command 的参数?传入字符串不会产生错误。

【问题讨论】:

    标签: typescript generics


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 2019-02-17
      相关资源
      最近更新 更多