如果我有这样的功能:
function say(message: string) {
alert(message);
return say;
}
它有一个有趣的属性,我可以链接调用它:
say("Hello,")("how")("are")("you?");
如果我在第一次调用中传递一个数字,编译器会生成一个警告,但是它允许我将数字放入后续调用中。
say("Hello")(1)(2)(3)(4)
我需要在say
函数中添加什么类型的注释,以便在将无效类型传递给链式调用时使编译器生成警告?
答案 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');