[英]How can I annotate recursive types in TypeScript?
If I have a function like this: 如果我有这样的功能:
function say(message: string) {
alert(message);
return say;
}
it has the interesting property that I can chain calls to it: 它有一个有趣的属性,我可以链接调用它:
say("Hello,")("how")("are")("you?");
The compiler will generate a warning if I pass a number into the first call, but it will allow me to put numbers into subsequent calls. 如果我将数字传递给第一个调用,编译器将生成警告,但它允许我将数字放入后续调用中。
say("Hello")(1)(2)(3)(4)
What type annotation do I need to add to the say
function to make the compiler generate warnings when I pass in invalid types to the chained calls? 当我将无效类型传递给链式调用时,我需要向say
函数添加什么类型的注释以使编译器生成警告?
A type that references itself must have a name. 引用自身的类型必须具有名称。 For example, 例如,
interface OmegaString {
(message: string): OmegaString;
}
then you can annotate say
as an OmegaString
, 然后你可以注释say
作为OmegaString
,
function say(message: string): OmegaString {
alert(message);
return say;
}
then the following code will type-check. 然后以下代码将进行类型检查。
say("Hello,")("how")("are")("you?");
but the following will not, 但以下不会,
say("Hello")(1)(2)(3)(4)
When you are using a class instead of a function, you can use the this
type to express the fact that a method returns the instance it was called on (chaining methods) . 当您使用类而不是函数时,可以使用this
类型来表示方法返回它被调用的实例(链接方法)这一事实。
Without 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');
With this
: 有了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');
When a function is chainable you can type it with an interface: 当函数是可链接的时,您可以使用接口键入它:
function say(text: string): ChainableType { ... }
interface ChainableType {
(text: string): ChainableType;
}
say('Hello')('World');
If a function has other properties or methods (like jQuery(str)
vs jQuery.data(el)
), you can type the function itself as an interface: 如果函数具有其他属性或方法(如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');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.