web-dev-qa-db-ja.com

エラー:型が呼び出しシグネチャを欠いている式を呼び出すことはできません

私はTypeScriptの初心者で、2つのクラスがあります。私は親クラスにいます:

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が返す関数には呼び出しシグネチャがあります。関数の型付けについて何か重要なことを誤解していると思いますが、それが何であるかわかりません。

ありがとうございます。

80
Justin

それが返す関数は呼び出しシグネチャを持っています、しかしあなたはTypeScriptにシグネチャに: anyを加えることによってそれを完全に無視するように言いました。

しないでください。

51
SLaks

「コールシグネチャがない型の式は起動できません。」

あなたのコードで:

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を関数として呼び出すことはできません。そのため、エラーが発生しました:this.toggleBody(true);this.toggleBody(false);

29
basarat

これを分解しましょう:

  1. エラーは言う

    型に呼び出し署名がない式を呼び出すことはできません。

  2. コード:

問題はこの行にありますpublic toggleBody: string;

これらの行との関係:

...
return this.toggleBody(true);
...
return this.toggleBody(false);
  1. 結果:

toggleBodystringですが、call signature(つまり、ラムダ、プロシージャ、関数、メソッドなどの呼び出し可能なものの構造)を持つもののように扱うことJSでは単なる機能です。)。宣言をpublic toggleBody: (arg: boolean) => boolean;に変更する必要があります。

追加の詳細:

「呼び出す」とは、関数の呼び出しまたは適用を意味します。

JavaScriptの「式」は基本的に値を生成するものなので、this.toggleBody()は式としてカウントされます。

「type」はこの行で宣言されますpublic toggleBody: string

「呼び出しシグネチャがありません」これは、シグネチャ(つまり、呼び出せるものの構造:ラムダ、プロシージャ、関数、メソッドなど)を持たないthis.toggleBody()を呼び出そうとするためです。と呼ばれます。 this.toggleBodyは文字列のように機能するものだとおっしゃいました。

言い換えれば、エラーは言っています

式(this.toggleBody)の型(:string)には呼び出し署名がないため、式(this.toggleBody)を呼び出すことはできません(bcには文字列署名があります。)

19
Taysky

私はあなたが欲しいものがだと思います:

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)にあります。あなたが本当にしていることは言うことです:これはプロパティ名で提供される関数であり、そのプロパティを変更することを可能にする関数を返します。

makePropSetter<T>を使用すると、その関数を特定の型に固定できます。サブクラスのコンストラクタの<boolean>は、実際にはオプションです。あなたはtoggleBodyに代入しており、それは既に完全に指定された型を持っているので、TSコンパイラはそれ自身でそれを解決することができるでしょう。

次に、サブクラスでその関数を呼び出すと、戻り型は特定のシグネチャを持つ関数であると正しく理解されます。当然、toggleBodyも同じシグネチャを尊重する必要があります。

6
Andrew Miner

変数に型を追加してから戻ります。

例えば:

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

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

=>重要なのは、文字列[]型などを追加することです。

0
Afshin Ghazi

それはあなたが関数ではない何かを呼び出そうとしているということです

const foo = 'string'
foo() // error
0
Gunar Gessner

同じエラーメッセージが表示されました。私の場合、ES6 export default function myFunc構文とconst myFunc = require('./myFunc');を誤って混在させていました。

代わりにmodule.exports = myFunc;を使用して問題を解決しました。

0
Charlie Weems