エラー:コールシグネチャがない型の式を呼び出すことはできません


121

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

ありがとう!


1
togglrBodyあなたはそれが機能することにしたいため、文字列であってはならない
eavidan

1
@eavidanはい、これは実際にブール値を返す関数です。最初は文字列を返すと思っていました。それで私はそれを何に変えますか?
ジャスティン

以下のように思えるが何であれに、SetProp戻り、<T>(val: T) => T
eavidan

回答:


76

返される関数には呼び出し署名がありますが、Typescriptに: any署名を追加することで完全に無視するように指示しました。

しないでください。


進捗状況、ありがとうございます。ここで、「エラーTS2322:タイプ '<T>(val:T)=> T'はタイプ 'boolean'に割り当てられません」と表示されます。:anyを削除した場合。これが私が最初に:anyを追加した理由だと思います。実際に元のエラーも表示されます。
ジャスティン

1
これを行って変更public toggleBody: boolean;するpublic toggleBody: any;と、うまくいきます。
ジャスティン

1
@ジャスティンなぜあなたは他に何を期待しましたか?this.toggleBodyを返す必要があると主張していますが、これは割り当てbooleanた戻り値と一致していませんsetProp。実際に何を送信して何を返したいのかを考えずに、型をランダムに投げているように見えます。
jonrsharpe 2016

@jonrsharpeはい、それは理にかなっています。この場合はブール値を返しますが、一般的には任意を返します。だから私は何かを使わなければなりませんか?
Justin

9
この応答は、例を挙げて、物事を行うための正しい方法を説明することから利益を得ます。
Andre M

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;ます。stringaを関数として呼び出すことはできません。したがって、エラーの: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(:ラムダ、PROC、関数、メソッドなどでJSだけでカントーに機能します。つまり、呼び出すことができる何かの構造)。宣言をに変更する必要がありますpublic toggleBody: (arg: boolean) => boolean;

追加の詳細:

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

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

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

「呼び出し署名がない」これは、呼び出し可能なthis.toggleBody()署名(つまり、呼び出し可能なものの構造:ラムダ、プロシージャ、関数、メソッドなど)を持たないものを呼び出そうとしたためです。あなたthis.toggleBodyは紐のように振る舞うものだと言った。

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

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


4
これは最高の答えの1つです。私はそれらの定義をすべて知っていますが、警告メッセージを見ると、これらの用語すべてが1つの密な文章で、雑然とした脳には多すぎました。
チャム

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同じ署名を尊重する必要があります。


5

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

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

0

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

例えば:

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

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

=>重要な部分はstring []タイプなどを追加することです:


0

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

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


0

このエラーは、何かから値をリクエストしていて、関数呼び出しであるかのように最後に括弧を置いたときに、括弧が終了せずに値が正しく取得された場合に発生する可能性があります。たとえば、アクセスしているものがTypescriptのプロパティ 'get'である場合。

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

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

private get SuperCoolNumber(): number {
    let response = 42;
    return response;
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.