【问题标题】:How can I annotate recursive types in TypeScript?如何在 TypeScript 中注释递归类型?
【发布时间】:2012-10-02 18:19:13
【问题描述】:

如果我有这样的功能:

function say(message: string) {
    alert(message);
    return say;
}

它有一个有趣的属性,我可以链接调用它:

say("Hello,")("how")("are")("you?");

如果我将数字传递给第一次调用,编译器会生成警告,但它允许我将数字放入后续调用中。

say("Hello")(1)(2)(3)(4)

我需要在say 函数中添加什么类型注释以使编译器在我将无效类型传递给链式调用时生成警告?

【问题讨论】:

    标签: types typescript


    【解决方案1】:

    引用自身的类型必须有名称。例如,

    interface OmegaString {
        (message: string): OmegaString;
    }
    

    然后你可以将say注释为OmegaString

    function say(message: string): OmegaString {
        alert(message);
        return say;
    }
    

    那么下面的代码将进行类型检查。

    say("Hello,")("how")("are")("you?");
    

    但以下不会,

    say("Hello")(1)(2)(3)(4)
    

    【讨论】:

    • 您能否详细说明为什么它必须有一个名字?
    • @OldrichSvec Peter 完全正确。递归类型需要能够引用自身。给它一个名字允许它引用自己。
    【解决方案2】:

    可链式方法

    当您使用类而不是函数时,您可以使用this 类型来表示方法返回在(链接方法)上调用的实例。。 p>

    没有this

    class StatusLogger {
        log(message: string): StatusLogger { ... }
    }
    // this works
    new ErrorLogger().log('oh no!').log('something broke!').log(':-(');
    
    class PrettyLogger extends StatusLogger {
        color(color: string): PrettyLogger { ... }
    }
    // this works
    new PrettyLogger().color('green').log('status: ').log('ok');
    // this does not!
    new PrettyLogger().log('status: ').color('red').log('failed');
    

    this:

    class StatusLogger {
        log(message: string): this { ... }
    }
    class PrettyLogger extends StatusLogger {
        color(color: string): this { ... }
    }
    // this works now!
    new PrettyLogger().log('status:').color('green').log('works').log('yay');
    

    可链接函数

    当一个函数是可链接的,你可以用一个接口来输入它:

    function say(text: string): ChainableType { ... }
    interface ChainableType {
        (text: string): ChainableType;
    }
    say('Hello')('World');
    

    具有属性/方法的可链接函数

    如果函数有其他属性或方法(如jQuery(str) vs jQuery.data(el)),您可以将函数本身作为接口键入:

    interface SayWithVolume {
        (message: string): this;
        loud(): this;
        quiet(): this;
    }
    
    const say: SayWithVolume = ((message: string) => { ... }) as SayWithVolume;
    say.loud = () => { ... };
    say.quiet = () => { ... };
    
    say('hello').quiet()('can you hear me?').loud()('hello from the other side');
    

    【讨论】:

      猜你喜欢
      • 2018-05-30
      • 2013-09-17
      • 2018-06-10
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      相关资源
      最近更新 更多