typescript - ¿Por qué una propiedad privada es parte de la interfaz?
Considera lo siguiente:
class X {
bar() {
return "bar"
}
constructor(private readonly x: number){}
}
interface Y extends X {
}
const f = (y: Y) => { console.log(y.bar()); }
f({ bar: () => "tavern"});
No se compila, porque falta x.
f({ bar: () => "tavern", x: 1});
no se compila porque x no es privado.
Reescribiendo el código para que sea posible declarar el x como privado
class Y implements X {
bar() {
return "tavern"
}
private x = 1;
}
es rechazado porque "los tipos tienen declaraciones separadas".
La única solución que he encontrado es eliminar el private del constructor.
Lo que realmente me gustaría hacer es lo primero: no me importan las propiedades privadas de la clase, y especialmente no me importan los miembros privados declarados dentro del constructor.
Mis dos preguntas son:
- ¿Por qué es este el caso?
- ¿Qué, si es que hay algo, puedo hacer para no tener que preocuparme por las propiedades privadas?
Respuesta #1
Ryan Cavanaugh, líder de desarrollo del equipo de Typescript en Microsoft, escribió:
Permitir que los campos privados estén ausentes sería un problema enorme, no un simple asunto trivial de solidez.
Considera este código:
class Identity { private id: string = "secret agent"; public sameAs(other: Identity) { return this.id.toLowerCase() === other.id.toLowerCase(); } } class MockIdentity implements Identity { public sameAs(other: Identity) { return false; } }
MockIdentityes una versión compatible con el público deIdentity, pero intentar usarla como tal hará que falle ensameAscuando una copia no simulada interactúe con una copia simulada.
Lo cual apesta. Tiene perfecto sentido, pero apesta.
Pero encontré una solución alternativa que resuelve mi problema:
type Public<T> = {
[P in keyof T]: T[P];
};
class X {
bar() {
return "bar"
}
constructor(private readonly x: number){}
}
interface Y extends Public<X> { }
const f = (y: Y) => { console.log(y.bar()); }
f({ bar: () => "tavern"});
Esto me permite simular tipos complejos de manera confiable, sin tener que simular también datos privados.
Esto es seguro en un contexto de prueba, donde las instancias simuladas y las instancias reales nunca interactúan.
