web-dev-qa-db-fra.com

Typescript: expression 'nouvelle', dont la cible n'a pas de signature de construction, a implicitement un type 'any' .ts (7009)

Voici le code qui fonctionne le mieux pour afficher les erreurs personnalisées dans Chrome Devtools, Node.js, etc. Basé sur cette réponse StackOverflow .

function CustomErr (message) {
  var err = new Error(message)
  Object.setPrototypeOf(err, CustomErr.prototype)
  return err
}

CustomErr.prototype = Object.create(Error.prototype, {
  name: { value: 'Custom Error', enumerable: false }
})

Cependant, lorsque je le convertis en TypeScript:

function CustomErr (message: string) {
  var err = new Error(message)
  Object.setPrototypeOf(err, CustomErr.prototype)
  return err
}

CustomErr.prototype = Object.create(Error.prototype, {
  name: { value: 'Custom Error', enumerable: false }
})

L'appel de throw new CustomErr("something went wrong") montre cette erreur:

'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.ts(7009)

Que puis-je faire pour taper correctement mon code? Si vous pouvez trouver une autre solution de code équivalente, n'hésitez pas à la suggérer, mais elle DOIT avoir le même comportement dans Chrome DevTools (cette seule de toutes les solutions que j'ai essayées affiche bien un nom d'erreur personnalisé). Merci!

[~ # ~] edit [~ # ~] : Je dois prendre en charge les anciens navigateurs, donc je ne peux pas utiliser les classes ES6. Je préférerais ne pas transpiler les classes vers ES6 parce que je crée une bibliothèque légère et qu'un polyfill de classe représente à lui seul 10% de la taille de mon code.

Alors pour récapituler, comment puis-je annoter le code que j'ai maintenant?

5
Ben Gubler

Vous pouvez déclarer une classe, mais l'implémenter avec une fonction. De cette façon, la sortie (le javascript résultant) ne sera pas affectée, mais TypeScript traitera le CustomErr comme un "nouveau":

declare class CustomErr extends Error {
    constructor(message: string);
}

function CustomErr(message: string) {
    var err = new Error(message)
    Object.setPrototypeOf(err, CustomErr.prototype)
    return err
}

CustomErr.prototype = Object.create(Error.prototype, {
    name: { value: 'Custom Error', enumerable: false }
})

throw new CustomErr("something went wrong") // no error now

Aire de jeux

1
Aleksey L.

Je n'ai toujours aucune idée de comment annoter mon code, mais simplement changer throw new CustomErr('err') en throw CustomErr('err') a résolu mon problème. Bien que JS vous permette d'utiliser le constructeur new, TypeScript ne le fait pas.

1
Ben Gubler

Quelques choses. Quel est le but de faire du code comme celui-ci, pourquoi ne pas laisser TypeScript compiler le code jusqu'à es5, ou Babel. Je viens de copier et coller le code yow ici et il compile: https://codepen.io/jaraolveda/pen/ExaWbxy Ce qui me dit que vous allez un peu trop lourd sur le tsconfig.json. Mais si vous voulez vraiment que je voie comment faire quelque chose comme ça. Voici un exemple de la façon de le faire Comment implémenter une interface TypeScript dans une "classe" de style es5?

0
Ernesto