TypeScript-typförsäkringsfel: 'Detta uttryck kan inte anropas Typ '...' har inga anropssignaturer' orsakas av ett saknat semikolon


Detta är en mycket nedskalad version av vår ursprungliga kod:

  const start: number = 10
  const end: number = 20
  (someElement as HTMLInputElement).setSelectionRange(start, end)

Sedan fanns det en fin liten röd krum linje under 20. Som indikerade detta fel: Detta uttryck är inte anropbart Typ 'Number' har inga anropssignaturer. Vi räknade ut att lösningen är att lägga till ett semikolon:

  const start: number = 10
  const end: number = 20;
  (someElement as HTMLInputElement).setSelectionRange(start, end)

Vet någon varför det skulle kompileras på det sättet? Jag antar att typencript som kompileras till javascript tolkar den koden som nedan och försöker anropa end-variabeln som en funktion.

  const start: number = 10
  const end: number = 20(someElement as HTMLInputElement).setSelectionRange(start, end)

Svar #1

Detta beteende är inte specifikt för TypeScript; problemet du har är detsamma som du skulle få med vanlig JavaScript. TypeScript-kompilatorn väljer inte att kompilera korrekt TypeScript till felaktig JavaScript; istället transpilerar den samvetsgrant konstig TypeScript till motsvarande konstig JavaScript.

I allmänhet gäller inte automatisk semikoloninsättning om nästa token efter radslutet är möjligtvis syntaktiskt giltig, de enda undantagen är vissa specifika ställen där radslut är förbjudna (se MDN-länken ovan för en lista över dessa ställen). Den öppna parentesen ( efter 20 kan uppenbarligen tolkas som början på ett funktionsanrop, vilket är syntaktiskt giltigt. Och eftersom ett radslut inte är förbjudet efter 20, sätts inget semikolon in.

I TypeScript får du ett kompileringsfel som varnar dig för att du anropar 20 vilket inte har någon anropssignatur. Det felet är en bra sak, eftersom det ger dig en möjlighet att fixa din kod genom att sätta dit ditt eget semikolon, innan du når körningstid. För om du skulle skriva koden ovan i vanlig JavaScript (t.ex. utan typförsäkringar) skulle JavaScript-körtiden tolka koden på samma sätt och du skulle få ett körningsfel istället för en kompileringsvarning:

// This is plain JS, not TS 
try {
  const someElement = document.getElementsByTagName("input").item(0);
  const start = 10
  const end = 20
  (someElement).setSelectionRange(start, end)
} catch (e) {
  console.log("OOPS I CAUGHT AN ERROR");
  console.log(e.message); // 20 is not a function
}

Om du kör det kodstycket (utan någon TypeScript-kompilator i sikte) kommer du att se att din webbläsares JavaScript-runtime ger ett TypeError att 20 inte är en giltig funktion.

Relaterade artiklar