Помилка. Неможливо викликати вираз, типу якого відсутній підпис дзвінка


121

Я абсолютно новачок в машинописі і маю два класи. У батьківському класі я маю:

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

У дитячому класі я:

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

І showMore, і ShowLess дають мені помилку: "Неможливо викликати вираз, типу якого відсутній підпис дзвінка".

Але я думаю, що функція, яку повертає setProp, має підпис дзвінка? Я думаю, що я розумію щось важливе щодо типізації функцій, але я не знаю, що це таке.

Дякую!


1
togglrBodyне повинно бути рядком, оскільки ви хочете, щоб це була функція
eavidan

1
@eavidan так, це функція, яка фактично повертає булева. Спочатку я думав, що це поверне рядок. То що я можу змінити?
Джастін

Який би setProp не повертався, схоже<T>(val: T) => T
eavidan

Відповіді:


76

Функція, яку він повертає, має підпис дзвінка, але ви сказали Typescript повністю ігнорувати це, додавши : anyйого в підпис.

Не робіть цього.


Гаразд прогрес, спасибі! Тепер я отримую "помилка TS2322: Type '<T> (val: T) => T' не можна присвоїти типу" boolean "." Якщо я видалю: будь-який. Я думаю, саме тому я додав: в першу чергу будь-який. Я фактично все ще отримую оригінальні помилки.
Джастін

1
Якщо я це роблю і зміна public toggleBody: boolean;на public toggleBody: any;нього працює.
Джастін

1
@ Джустін, чому ти чекав чогось іншого? Ви заявляєте, що this.toggleBodyмає повернутись boolean, але це не відповідає значенню повернення, setPropяке ви призначили йому. Ви, здається, просто безладно кидаєтеся в типи, не замислюючись про те, що ви насправді хочете відправити та повернути.
jonrsharpe

@jonrsharpe Добре так, це має сенс. У цьому випадку він повертає булевий, але загалом повертає будь-який. Так що я повинен використовувати будь-який?
Джастін

9
Ця відповідь отримала б користь від пояснення правильного способу робити приклади.
Андре М

38

"Неможливо викликати вираз, типу якого відсутній підпис дзвінка."

У вашому коді:

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

У вас є public toggleBody: string;. Ви не можете викликати stringфункцію a. Звідси помилки на: this.toggleBody(true);іthis.toggleBody(false);


28

Розберемо це:

  1. Помилка говорить

    Неможливо викликати вираз, типу якого відсутній підпис дзвінка.

  2. Код:

Проблема в цьому рядку public toggleBody: string;&

це відношення до цих рядків:

...
return this.toggleBody(true);
...
return this.toggleBody(false);
  1. Результат:

Твоя приказка toggleBody- це, stringале тоді ти трактуєш її як щось, що має call signature(тобто структуру чогось, що можна назвати: лямбда, прок, функції, методи тощо. У JS просто функціонує тхо). Потрібно змінити декларацію, щоб бути public toggleBody: (arg: boolean) => boolean;.

Додаткові деталі:

"виклик" означає ваш дзвінок або застосування функції.

"вираз" у Javascript - це в основному щось, що виробляє значення, тому this.toggleBody()вважається виразом.

"type" оголошено в цьому рядку public toggleBody: string

"не вистачає підпису дзвінка", це тому, що ви намагаєтеся викликати те, this.toggleBody()що не має підпису (тобто структуру того, що можна назвати: лямбдас, процедур, функції, методи тощо), які можна викликати. Ви сказали, this.toggleBodyце щось, що діє як струна.

Іншими словами помилка говорить

Неможливо викликати вираз (this.toggleBody), оскільки його типу (: string) не вистачає підпису виклику (bc він має рядковий підпис.)


4
Це одна з найкращих відповідей, коли-небудь! Я знаю всі ці визначення, але коли я побачив попереджувальне повідомлення, всі ці терміни в одному щільному реченні були занадто великими для мого захаращеного мозку.
ч

6

Я думаю, що ти хочеш:

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

Важлива зміна полягає в setProp(тобто makePropSetterв новому коді). Що ви там дійсно робите, це сказати: це функція, яка надала ім'я властивості, поверне функцію, яка дозволяє змінити цю властивість.

<T>На makePropSetterдозволяє заблокувати цю функцію , щоб тип конкретного. Конструктор <boolean>підкласу фактично необов’язковий. Оскільки ви присвоюєте toggleBodyцей тип і вже має вказаний тип, компілятор TS зможе опрацювати його самостійно.

Потім у своєму підкласі ви викликаєте цю функцію, і тип повернення тепер належним чином розуміється як функція з певною підписом. Природно, вам потрібно буде toggleBodyповажати той самий підпис.



0

Додайте тип до змінної та поверніться.

Наприклад:

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

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

=> Важливою частиною є додавання рядка [] типу тощо:


0

У мене було те саме повідомлення про помилку. У моєму випадку я ненароком змішав export default function myFuncсинтаксис ES6 з const myFunc = require('./myFunc');.

Використовуючи module.exports = myFunc;натомість вирішено проблему.


0

Ця помилка може бути викликана, коли ви щось вимагаєте від значення і ставите круглі дужки в кінці, як якщо б це функція виклику, але значення витягується правильно, не закінчуючи дужки. Наприклад, якщо те, що ви отримуєте доступ, це властивість "отримати" в Typescript.

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

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

private get SuperCoolNumber(): number {
    let response = 42;
    return response;
};
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.