如何在TypeScript中注释递归类型?

时间:2012-10-12 00:14:07

标签: types typescript

如果我有这样的功能:

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:18)

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

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)

答案 1 :(得分:0)

可连接方法

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

没有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');