microsoft / microsoft/TypeScript

Allow type annotation on catch clause variable

Aperta
#20,024 83 commenti 306 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Awaiting More Feedback Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

TypeScript Version: 2.6.1

const rejected = Promise.reject(new Error());

async function tryCatch() {
  try {
    await rejected;
  } catch (err: Error) { // TS1196: Catch clause variable cannot have a type annotation
    // Typo, but `err` is `any`, so it results in runtime error
    console.log(err.mesage.length);
  }
}

function promiseCatch() {
  rejected.catch((err: Error) => { // OK
    // Compiler error; Yay!
    console.log(err.mesage.length);
  });
}

This was discussed in #8677 and #10000. It was closed as "fixed" in #9999, but as far as I can tell neither of the issues was actually resolved. In either event, I'd like to make a case for allowing type annotations in catch clauses.

Especially with the introduction of downlevel async functions, I'd suggest that disallowing catch clause type annotations leads to less safe code. In the example, the two methods of handling the promise are functionally equivalent, but one allows you to type the error, and the other doesn't. Without writing extra code for the try/catch version (if (err instanceof Error) { or const e: Error = err or something), you'll get a runtime error that you wouldn't get with the pure Promise version.

The primary rationale for not allowing this is that any object can be thrown, so it's not guaranteed to be correct. However, most of the benefit of TypeScript comes from making assertions about your and other people's code that can't be strictly guaranteed (especially when importing JavaScript). And unless one would argue that the Promise catch function also shouldn't allow a type annotation on the error parameter, this argument seems to make very little practical sense.

I believe one of the other arguments against is that it might be confusing, as it looks like the typed exception handling you might see in other languages (e.g., Java), and folks may think the catch will only catch errors of the annotated type. I don't personally believe that's a legitimate issue, but if it really is I'd propose at least allowing a catch (err as Error) { syntax or similar as a way of emphasizing that it's a type assertion.

If nothing else at all, it seems that there should be a way to trigger a warning (similar to an implicit any warning) when using an untyped err directly within a catch block.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Iniziare dagli esempi nell’issue e leggere le discussioni in #8677, #10000 e #9999. Definire quale sintassi di annotazione o asserzione per le clausole catch e quale comportamento degli avvisi debbano essere supportati, quindi verificare che il comportamento scelto risolva la discrepanza tra async try/catch e Promise.catch.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.