Vous ne pouvez pas utiliser un ES2015 ou laterclass
pour vous faire appeler un constructeur sans le mot-clé new
. À l'étape 2 de la section 9.2.1 des documents liés, l'appel d'un constructeur de classe sans le mot-clé new
doit entraîner le lancement d'un TypeError
. (Si vous ciblez ES5 dans TypeScript, vous obtiendrez quelque chose qui fonctionne à l'exécution, mais si vous ciblez ES2015 ou au-dessus, vous obtiendrez des erreurs d'exécution.) Il est préférable de ne pas le faire. -ES2015 fonction constructeur à la place. Par ailleurs, la signature new(arg: number)
nécessite un type de retour. Par exemple:
interface A {
(): string;
new(arg: number): AInstance; // return something
GetValue(): number;
}
// define the instance type
interface AInstance {
instanceMethod(): void;
}
est ici une façon de mettre en oeuvre. Tout d'abord, faire une class
pour AInstance
:
class _A implements AInstance {
constructor(arg: number) { } // implement
instanceMethod() { } // implement
}
Ensuite, une fonction qui peut être appelée avec ou sans new
:
const AFunctionLike =
function(arg?: number): AInstance | string {
if (typeof arg !== "undefined") {
return new _A(arg);
}
return "string";
} as { new(arg: number): AInstance,(): string };
J'ai décidé que si vous appelez AFunctionLike
avec un argument vous obtiendra un AInstance
, sinon vous obtiendrez un string
. Vous pouvez également vérifier explicitement si new
a été utilisé, via new.target, si votre runtime est compatible.
Notez également que je devais affirmer que AFunctionLike
est newable (avec la clause as
sur la dernière ligne) car il n'y a actuellement aucun autre moyen de dire tapuscrit qu'une fonction autonome peut être appelée avec new
.
Maintenant nous avons presque terminé. Nous pouvons déclarer une valeur de type A
comme suit:
const A: A = Object.assign(
AFunctionLike,
{
GetValue() {
return 1;
}
}
);
La valeur A
a été formée par la fusion AFunctionLike
avec un objet qui implémente GetValue()
. Vous pouvez utiliser Object.assign
ou spread syntax pour effectuer cette fusion.
C'est tout. Vous pouvez vérifier que cela fonctionne à l'exécution on the TypeScript Playground. Bonne chance!