2012-10-12 31 views
10

Nếu tôi có một chức năng như thế này:Tôi làm cách nào để chú thích các loại đệ quy trong TypeScript?

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

nó có tính chất thú vị mà tôi có thể gọi chuỗi với nó:

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

Trình biên dịch sẽ tạo ra một cảnh báo nếu tôi vượt qua một số vào cuộc gọi đầu tiên, nhưng nó sẽ cho phép tôi đưa số vào các cuộc gọi tiếp theo.

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

kiểu gì chú thích sao tôi cần phải thêm vào say chức năng để làm cho trình biên dịch tạo ra các cảnh báo khi tôi vượt qua trong các loại hợp lệ để các cuộc gọi bị xiềng xích?

Trả lời

18

Loại tham chiếu phải có tên. Ví dụ,

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

sau đó bạn có thể chú thích say như một OmegaString,

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

sau đó đoạn mã sau sẽ gõ kiểm tra.

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

nhưng sau sẽ không,

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

Ông có thể xin hãy giải thích về việc tại sao nó phải có tên? –

+2

@OldrichSvec Bạn cần một tên để có thể tham chiếu đến nó, trừ khi có một số từ khóa tự tham chiếu đặc biệt, mà IMO sẽ không được sử dụng thường xuyên đủ để có giá trị gia tăng. –

+0

@OldrichSvec Peter chính xác. Loại đệ quy cần có khả năng tự tham chiếu. Đặt tên cho phép nó tự tham chiếu. – chuckj

0

phương pháp thể kết nối

Khi bạn đang sử dụng một lớp thay vì một chức năng, bạn có thể sử dụng các loại this để diễn tả thực tế là một phương pháp trả về thể hiện nó được gọi trên (phương pháp chuỗi).

Without 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'); 

Với 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'); 

thể kết nối chức năng

Khi một chức năng là thể kết nối bạn có thể gõ nó với một giao diện:

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

chức năng thể kết nối với các thuộc tính/phương pháp

Nếu một hàm có tính chất hoặc các phương pháp (như jQuery(str) vs jQuery.data(el)), bạn có thể gõ các chức năng chính nó như là một giao diện khác:

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'); 
Các vấn đề liên quan