2016-09-25 16 views
26

Tôi là người mới sử dụng bản đánh chữ và tôi có hai lớp. Trong lớp cha mẹ tôi có:Lỗi: Không thể gọi biểu thức có loại thiếu chữ ký cuộc gọi

abstract class Component { 
    public deps: any = {}; 
    public props: any = {}; 

    public setProp(prop: string): any { 
    return <T>(val: T): T => { 
     this.props[prop] = val; 
     return val; 
    }; 
    } 
} 

trong lớp con tôi có: "Không thể gọi một biểu thức có loại thiếu một chữ ký cuộc gọi"

class Post extends Component { 
    public toggleBody: string; 

    constructor() { 
    this.toggleBody = this.setProp('showFullBody'); 
    } 

    public showMore(): boolean { 
    return this.toggleBody(true); 
    } 

    public showLess(): boolean { 
    return this.toggleBody(false); 
    } 
} 

Cả showMore và ShowLess cung cấp cho tôi những lỗi,

Nhưng hàm setProp trả về CÓ chữ ký cuộc gọi, tôi nghĩ vậy? Tôi nghĩ rằng tôi hiểu lầm một cái gì đó quan trọng về cách gõ các chức năng, nhưng tôi không biết nó là gì.

Cảm ơn!

+1

'togglrBody' không nên là một chuỗi, vì bạn muốn nó là hàm – eavidan

+0

@eavidan có đó là hàm thực sự trả về boolean. Ban đầu tôi nghĩ nó sẽ trả về một chuỗi. Vậy tôi phải đổi nó thành gì? – Justin

+0

Bất kỳ setProp nào trả về, có vẻ như ' (val: T) => T' – eavidan

Trả lời

16

Hàm trả về có chữ ký cuộc gọi, nhưng bạn đã yêu cầu Typecript hoàn toàn bỏ qua điều đó bằng cách thêm : any vào chữ ký của nó.

Đừng làm điều đó.

+0

Ok tiến trình, Cảm ơn! Bây giờ tôi nhận được "lỗi TS2322: Loại ' (val: T) => T' không thể gán cho loại 'boolean'." Nếu tôi loại bỏ: bất kỳ. Tôi nghĩ rằng đây là lý do tại sao tôi thêm: bất kỳ ở nơi đầu tiên. Tôi thực sự vẫn nhận được các lỗi ban đầu là tốt. – Justin

+0

Nếu tôi làm điều này và thay đổi 'public toggleBody: boolean;' thành 'public toggleBody: any;' nó hoạt động. – Justin

+1

@Justin tại sao bạn lại mong đợi điều gì khác? Bạn yêu cầu 'this.toggleBody' sẽ trả về' boolean', nhưng điều đó không nhất quán với giá trị trả về của 'setProp' mà bạn đã gán cho nó. Bạn dường như chỉ ngẫu nhiên ném vào các loại mà không suy nghĩ về những gì bạn thực sự muốn gửi và trả lại. – jonrsharpe

10

"Cannot invoke an expression whose type lacks a call signature."

Trong mã của bạn:

class Post extends Component { 
    public toggleBody: string; 

    constructor() { 
    this.toggleBody = this.setProp('showFullBody'); 
    } 

    public showMore(): boolean { 
    return this.toggleBody(true); 
    } 

    public showLess(): boolean { 
    return this.toggleBody(false); 
    } 
} 

Bạn có public toggleBody: string;. Bạn không thể gọi số string làm chức năng. Do đó lỗi trên: this.toggleBody(true);this.toggleBody(false);

3

Tôi nghĩ rằng những gì bạn muốn là:

abstract class Component { 
    public deps: any = {}; 
    public props: any = {}; 

    public makePropSetter<T>(prop: string): (val: T) => T { 
    return function(val) { 
     this.props[prop] = val 
     return val 
    } 
    } 
} 

class Post extends Component { 
    public toggleBody: (val: boolean) => boolean; 

    constructor() { 
    super() 
    this.toggleBody = this.makePropSetter<boolean>('showFullBody') 
    } 

    showMore(): boolean { 
    return this.toggleBody(true) 
    } 

    showLess(): boolean { 
    return this.toggleBody(false) 
    } 
} 

Sự thay đổi quan trọng là trong setProp (ví dụ: makePropSetter trong mã mới). Những gì bạn đang thực sự làm ở đó là để nói: đây là một hàm, được cung cấp với một tên thuộc tính, sẽ trả về một hàm cho phép bạn thay đổi thuộc tính đó.

<T> trên makePropSetter cho phép bạn khóa chức năng đó thành một loại cụ thể. <boolean> trong hàm tạo của lớp con thực sự là tùy chọn. Vì bạn đang gán cho toggleBody và đã có loại được chỉ định đầy đủ, trình biên dịch TS sẽ có thể tự làm việc đó.

Sau đó, trong lớp con của bạn, bạn gọi hàm đó và kiểu trả về giờ đây được hiểu đúng là một hàm có chữ ký cụ thể. Đương nhiên, bạn sẽ cần phải có toggleBody tôn trọng cùng một chữ ký đó.

Các vấn đề liên quan