Búsqueda de sitios web

javascript - cierres de TypeScript - una solución "casi"


Uno de mis mayores irritantes con TypeScript es el hecho de que compila todos los métodos (independientemente del modificador de acceso) al prototipo.

Ejemplo

class Example {
    public getString(): string {
        return "Hello World";
    }

    private getNumber(): number {
        return 123;
    }
}

Como sabemos, los modificadores de acceso solo se verifican en la compilación, por lo que son ignorados por el JavaScript emitido. Una manera en que los desarrolladores de JavaScript han aprendido a mitigar esto es usando closures (bueno, sabemos que hay penalizaciones de rendimiento al usar closures, pero creo que hay casos en los que los closures son absolutamente necesarios).

Ejemplo

var Example = (function () {
    function Example() {
        this.getString = function () {
            return "Hello World";
        }

        var getNumber = function() {
            return 123;
        }
    }

    return Example;
})();

El ejemplo anterior respeta el acceso público/privado.

He descubierto que al usar la sintaxis lambda podemos declarar métodos de cierre públicos dentro de TypeScript.

Ejemplo

class Example {
    getString = (): string => {
        return "Hello World";
    }
}

No es particularmente bonito, pero funciona.

Lo que me gustaría saber es: ¿Cómo declararía cierres privados en TypeScript?

Ejemplo

class Example {

    // TypeScript doesn't like this!
    var getNumber = (): number => {
        return 123;
    }
}

Vea más sobre este dolor de cabeza aquí: https://github.com/Microsoft/TypeScript/issues/2940

Respuesta #1

TypeScript trae tipos y accesores a ES6 (y verifica ambos estáticamente). La palabra clave class en TypeScript es la palabra clave estándar class de ES6. No hay cierres privados en las clases de ES6. Esta sintaxis no es válida en ES6:

class Example {
    var v = /* ... */; // invalid in ES6
}

Si necesitas declarar un cierre que encapsule variables, deberías usar la forma clásica de JavaScript. Recomiendo encarecidamente aprovechar las interfaces de TS:

interface NamedObject {
    getName(): string;
}

let createNamedObject = function (name = 'John'): NamedObject {
    return {
        getName: function () {
            return name;
        }
    };
};

let obj: NamedObject = createNamedObject();

Si realmente quieres hacer métodos de clase con cierres, puedes hacer esto:

class BadPerformance {
    public getName: () => string;

    constructor(name = 'John') {
        this.getName = () => {
            return name;
        };
    }
}

Respuesta #2

Como sabemos, los modificadores de acceso solo se verifican en la compilación, por lo tanto, son ignorados por el JavaScript emitido.

Eso es porque la privacidad en este contexto es la privacidad de la API frente a otros desarrolladores. Si quieres que sepan que el método es privado, proporciónales un archivo .d.ts para que su editor pueda saberlo o no lo documentos en la Documentación de la API.

En JavaScript, la documentación a menudo se considera la API.

Lo que me gustaría saber es: ¿Cómo declararía cierres privados en TypeScript?

Puedes crear funciones en el constructor que las declararían en la instancia y no en el prototipo. Esto te permitiría usar un cierre; también va en contra de la herencia prototípica y la naturaleza de TypeScript y JavaScript.

Artículos relacionados