Lỗi: Không thể gọi một biểu thức có kiểu thiếu chữ ký cuộc gọi


121

Tôi là thương hiệu mới đối với bảng chữ, và tôi có hai lớp. Trong lớp cha, tôi có:

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;
    };
  }
}

Ở lớp con tôi có:

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 đều cho tôi lỗi "Không thể gọi biểu thức có kiểu thiếu chữ ký cuộc gọi".

Nhưng hàm setProp trả về KHÔNG có chữ ký cuộc gọi, tôi nghĩ vậy? Tôi nghĩ rằng tôi đang hiểu sai điều gì đó quan trọng về cách đánh máy của các hàm, nhưng tôi không biết nó là gì.

Cảm ơn!


1
togglrBodykhông nên là một chuỗi, vì bạn muốn nó là một hàm
eavidan

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

Dù setProp trả về, có vẻ như<T>(val: T) => T
eavidan

Câu trả lời:


76

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

Đừng làm vậy.


Ok tiến độ, Cảm ơn! Bây giờ tôi nhận được "lỗi TS2322: Loại '<T> (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ĩ đây là lý do tại sao tôi đã thêm: bất kỳ ngay từ đầu. Tôi thực sự vẫn nhận được các lỗi ban đầu.
Justin

1
Nếu tôi làm điều này và thay đổi public toggleBody: boolean;để 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 xác nhận quyền sở hữu this.toggleBodysẽ trả lại boolean, nhưng điều đó không phù hợp với giá trị trả lại setPropmà bạn đã chỉ định cho nó. Bạn dường như chỉ ngẫu nhiên ném các loại mà không nghĩ về những gì bạn thực sự muốn gửi và trả lại.
jonrsharpe

@jonrsharpe Ok vâng, điều đó có ý nghĩa. Trong trường hợp này, nó trả về một boolean, nhưng nói chung nó trả về bất kỳ. Vì vậy, tôi phải sử dụng bất kỳ?
Justin

9
Phản hồi này sẽ có lợi khi giải thích cách làm đúng để làm mọi việc, kèm theo một ví dụ.
Andre M

38

"Không thể gọi một biểu thức có kiểu thiếu chữ ký cuộc gọi."

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 a stringdưới dạng một hàm. Do đó lỗi trên: this.toggleBody(true);this.toggleBody(false);


28

Hãy chia nhỏ điều này:

  1. Lỗi nói

    Không thể gọi một biểu thức có kiểu thiếu chữ ký cuộc gọi.

  2. Mật mã:

Vấn đề là ở dòng này public toggleBody: string;&

nó liên quan đến những dòng này:

...
return this.toggleBody(true);
...
return this.toggleBody(false);
  1. Kết quả:

Câu nói của bạn toggleBodylà a stringnhưng sau đó bạn xử lý nó như một thứ gì đó có a call signature(tức là cấu trúc của một thứ có thể được gọi là: lambdas, proc, functions, method, v.v. Trong JS chỉ là function tho.). Bạn cần thay đổi khai báo thànhpublic toggleBody: (arg: boolean) => boolean; .

Chi tiết bổ sung:

"gọi" có nghĩa là bạn đang gọi hoặc áp dụng một hàm.

"một biểu thức" trong Javascript về cơ bản là một cái gì đó tạo ra một giá trị, vì vậy this.toggleBody()được tính là một biểu thức.

"loại" được khai báo trên dòng này public toggleBody: string

"thiếu chữ ký cuộc gọi" là do bạn đang cố gắng gọi một thứ gì this.toggleBody()đó không có chữ ký (tức là cấu trúc của một cái gì đó có thể được gọi là: lambdas, proc, các hàm, phương thức, v.v.) có thể được gọi. Bạn đã nói this.toggleBodylà một cái gì đó hoạt động như một chuỗi.

Nói cách khác, lỗi đang nói

Không thể gọi một biểu thức (this.toggleBody) vì kiểu (: string) thiếu chữ ký cuộc gọi (bc nó có một chữ ký chuỗi.)


4
Đây là một trong những câu trả lời tốt nhất, bao giờ hết! Tôi biết tất cả các định nghĩa đó nhưng khi tôi nhìn thấy thông điệp cảnh báo tất cả các thuật ngữ đó, trong một câu dày đặc, quá sức đối với bộ não lộn xộn của tôi.
cham

6

Tôi nghĩ 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)
  }
}

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

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

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


5

Nó có nghĩa là bạn đang cố gắng gọi một cái gì đó không phải là một hàm

const foo = 'string'
foo() // error

0

Thêm một loại vào biến của bạn và sau đó trả về.

Ví dụ:

const myVariable : string [] = ['hello', 'there'];

const result = myVaraible.map(x=> {
  return
  {
    x.id
  }
});

=> Phần quan trọng là thêm chuỗi [] type vv:


0

Tôi đã có cùng một thông báo lỗi. Trong trường hợp của tôi, tôi đã vô tình trộn export default function myFunccú pháp ES6 vớiconst myFunc = require('./myFunc'); .

Sử dụng module.exports = myFunc;thay thế đã giải quyết được vấn đề.


0

Lỗi này có thể xảy ra khi bạn đang yêu cầu một giá trị từ một thứ gì đó và bạn đặt dấu ngoặc đơn ở cuối, như thể đó là một lệnh gọi hàm, nhưng giá trị được truy xuất chính xác mà không kết thúc dấu ngoặc đơn. Ví dụ: nếu những gì bạn đang truy cập là Thuộc tính 'get' trong Loại chỉ định.

private IMadeAMistakeHere(): void {
    let mynumber = this.SuperCoolNumber();
}

private IDidItCorrectly(): void {
    let mynumber = this.SuperCoolNumber;
}

private get SuperCoolNumber(): number {
    let response = 42;
    return response;
};
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.