javascript - ¿Cómo puedo devolver una clase desde una función de TypeScript?
Estoy usando TypeScript con una biblioteca de inyección de dependencias que funciona de manera muy similar a Angular 1 - básicamente: registrar una fábrica con tus dependencias como argumentos.
Así es como registraría una clase en ES6
export let factory = () => {
return class Foo {}
};
Si escribo lo mismo en TypeScript:
export let factory = () => {
return class Foo {}
};
Falla al compilar con el error
error TS4025: La variable exportada 'factory' tiene o está usando un nombre privado 'Foo'.
¿Hay alguna manera de permitir que TypeScript devuelva una clase desde una función fábrica?
Respuesta #1
Respuesta rápida
cambia esto:
export let factory = () => {
return class Foo {}
};
a eso:
export let factory = () : any => {
return class Foo {}
};
Respuesta más larga
Este error podría ser activado/forzado por una configuración de tsconfig.json:
{
"compilerOptions": {
...
"declaration": true // this should be false or omitted
Pero esa no es la razón, es solo un desencadenante. La verdadera razón (como se discute aquí Error al exportar función que devuelve clase: La variable exportada tiene o está usando un nombre privado) proviene del compilador de Typescript
cuando el compilador de TS encuentra una instrucción como esta
let factory = () => { ...
debe empezar a adivinar cuál es el tipo de retorno, porque falta esa información (ver el marcador de posición : <returnType>):
let factory = () : <returnType> => { ...
en nuestro caso, TS descubrirá rápidamente que el type devuelto es fácil de adivinar:
return class Foo {} // this is returned value,
// that could be treated as a return type of the factory method
entonces, en caso de que tuviéramos esa declaración similar (esto no es lo mismo que la declaración original en absoluto, pero vamos a intentar usarla solo como un ejemplo para aclarar lo que sucede) podemos declarar correctamente el tipo de retorno:
export class Foo {} // Foo is exported
export let factory = () : Foo => { // it could be return type of export function
return Foo
};
ese enfoque estaría funcionando, porque la clase Foo está exportada, es decir, visible para el mundo exterior.
Volviendo a nuestro caso. Queremos devolver un tipo que no es exportado. Y luego, DEBEMOS ayudar al compilador de TS a decidir cuál es el tipo de retorno.
Podría ser explícito cualquiera:
export let factory = () : any => {
return class Foo {}
};
Pero aún mejor sería tener alguna interfaz pública
export interface IFoo {}
Y luego usa tal interfaz como tipo de retorno:
export let factory = () : IFoo => {
return class Foo implements IFoo {}
};
Respuesta #2
Respuesta tardía a una pregunta antigua:
Necesitas tener la clase definida fuera del método de fábrica y definir el valor de retorno usando 'typeof'.
class Foo {}
export const factory = (): typeof Foo => {
return Foo;
};
