Hata: Türünde çağrı imzası olmayan bir ifade çağırılamaz


121

Daktilo konusunda yepyeni ve iki sınıfım var. Ebeveyn sınıfında var:

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

Çocuk sınıfında var:

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

Hem showMore hem de ShowLess bana "Türünde arama imzası olmayan bir ifade başlatılamaz."

Ancak setProp'un döndürdüğü işlevin bir çağrı imzası var mıdır? Sanırım fonksiyon türleriyle ilgili önemli bir şeyi yanlış anlıyorum, ama ne olduğunu bilmiyorum.

Teşekkürler!


1
togglrBodybir işlev olmasını istediğiniz için bir dizge olmamalıdır
eavidan

1
@eavidan evet aslında bir boole döndüren bir fonksiyondur. Başlangıçta bir dize döndüreceğini düşündüm. Öyleyse neye değiştirmeliyim?
Justin

SetProp ne dönerse dönerse, öyle görünüyor<T>(val: T) => T
eavidan

Yanıtlar:


76

Döndürdüğü işlevin bir çağrı imzası vardır, ancak Typescript'e : anyimzasına ekleyerek bunu tamamen görmezden gelmesini söylediniz .

Bunu yapma.


Tamam ilerleme, teşekkürler! Şimdi "TS2322 hatası: '<T> yazın (val: T) => T', 'boolean' türüne atanamaz." Kaldırırsam: herhangi. Sanırım bu yüzden ekledim: her şeyden önce. Aslında yine de orijinal hataları alıyorum.
Justin

1
Ben bu ve değişimi yaparsanız public toggleBody: boolean;için public toggleBody: any;çalışıyor.
Justin

1
@Justin neden başka bir şey bekliyordun? this.toggleBodyGeri dönmesi gerektiğini iddia edersiniz boolean, ancak bu setProp, ona atadığınız dönüş değeri ile tutarlı değildir . Gerçekte ne göndermek ve geri dönmek istediğinizi düşünmeden rastgele türler atıyor gibisiniz.
jonrsharpe

@jonrsharpe Tamam, bu mantıklı. Bu durumda bir boole döndürür, ancak genel olarak herhangi birini döndürür. Yani herhangi birini kullanmalı mıyım?
Justin

9
Bu yanıt, işleri doğru şekilde yapmanın bir örnekle açıklanmasından fayda sağlayacaktır.
Andre M

38

"Türünde çağrı imzası olmayan bir ifade çağırılamaz."

Kodunuzda:

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

Var public toggleBody: string;. A'yı stringişlev olarak çağıramazsınız . Dolayısıyla şu hatalar: this.toggleBody(true);vethis.toggleBody(false);


28

Bunu parçalayalım:

  1. Hata diyor

    Türünde çağrı imzası olmayan bir ifade çağırılamaz.

  2. Kod:

Sorun bu satırda public toggleBody: string;ve

şu çizgilerle ilişkilidir:

...
return this.toggleBody(true);
...
return this.toggleBody(false);
  1. Sonuç:

Söyledikleriniz toggleBodybir stringama sonra ona a'ya sahip bir şey gibi davranıyorsunuz call signature(yani çağrılabilecek bir şeyin yapısı: lambdas, proc, işlevler, yöntemler, vb. JS'de sadece işlev tho.). Beyanı şu şekilde değiştirmeniz gerekir:public toggleBody: (arg: boolean) => boolean; .

Ekstra Ayrıntılar:

"çağırmak" bir işlevi aramanız veya uygulamanız anlamına gelir.

Javascript'teki "bir ifade" temelde bir değer üreten bir şeydir, bu nedenle this.toggleBody()bir ifade olarak sayılır.

Bu satırda "tür" belirtilir public toggleBody: string

"bir çağrı imzası yok" bunun nedeni, this.toggleBody()çağrılabilecek imzası olmayan (yani çağrılabilecek bir şeyin yapısı: lambdas, proc, işlevler, yöntemler, vb.) bir şeyi çağırmaya çalışmanızdır . this.toggleBodyİp gibi davranan bir şey dedin .

Başka bir deyişle hata diyor ki

Bir ifade (this.toggleBody) çağrılamaz çünkü türünde (: string) bir çağrı imzası yoktur (bc bir dize imzasına sahiptir.)


4
Bu şimdiye kadarki en iyi cevaplardan biri! Tüm bu tanımları biliyorum ama uyarı mesajını gördüğümde tüm bu terimler, tek bir yoğun cümlede, dağınık beynim için çok fazlaydı.
cham

6

Sanırım senin istediğin:

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

Önemli değişiklik setProp(yani,makePropSetter yeni kodda). Orada gerçekten yaptığınız şey şunu söylemektir: bu, bir özellik adıyla sağlanan bir işlevdir, bu özelliği değiştirmenize izin veren bir işlev döndürür.

Açık <T>, makePropSetterbu işlevi belirli bir türe kilitlemenizi sağlar. Alt <boolean>sınıfın yapıcısı aslında isteğe bağlıdır. Atama yaptığınız için toggleBodyve bu tür zaten tam olarak belirtilmiş olduğundan, TS derleyicisi bunu kendi başına çalıştırabilecektir.

Ardından, alt sınıfınızda bu işlevi çağırırsınız ve dönüş türünün artık belirli bir imzaya sahip bir işlev olduğu doğru bir şekilde anlaşılır. Doğal olarak, toggleBodyaynı imzaya saygı duymanız gerekir .


5

Fonksiyon olmayan bir şeyi aramaya çalıştığın anlamına gelir

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

0

Değişkeninize bir tür ekleyin ve ardından geri dönün.

Örneğin:

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

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

=> Önemli kısım, [] tipini vb. Eklemek:


0

Aynı hata mesajını aldım. Benim durumumda, istemeden ES6 export default function myFuncsözdizimini ile karıştırdım const myFunc = require('./myFunc');.

module.exports = myFunc;Bunun yerine kullanmak sorunu çözdü.


0

Bu hata, bir şeyden bir değer talep ettiğinizde ve sonuna parantez koyduğunuzda, sanki bir işlev çağrısıymış gibi, yine de değer parantez bitmeden doğru bir şekilde alınırsa ortaya çıkabilir. Örneğin, erişmekte olduğunuz şey Typescript'te bir Özellik 'get' ise.

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

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

private get SuperCoolNumber(): number {
    let response = 42;
    return response;
};
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.