One interesting feature of TypeScript is its ability to access instance properties and methods that have been declared as `private instanceProperty`, but not explicitly as `#instanceProperty`.
Despite this, TypeScript still performs type checking on this access, for example:
class SomeClass {
private __someProperty: string;
notPrivate: number;
constructor() {
this.__someProperty = "foo";
this.notPrivate = 7;
}
}
const instance = new SomeClass();
console.log(instance.notPrivate); // 7
console.log(instance.__someProperty); // compile error
// Property '__someProperty' is private and only accessible within class 'SomeClass'.
console.log(instance["notPrivate"]); // 7
console.log(instance["__someProperty"]); // "foo"
console.log(instance["nonExistentProp"]); // compile error w/ noImplicitAny
// Element implicitly has an 'any' type because expression of type
// '"nonExistentProp"' can't be used to index type 'SomeClass '.
// Property 'nonExistentProp' does not exist on type 'SomeClass '.
Due to this behavior, I began experimenting with a method to expose private properties explicitly. This is where I started:
export function unsafe_expose<Instance, InstanceProperty extends keyof Instance>(
instance: Instance,
property: InstanceProperty,
) {
return instance as unknown as Omit<Instance, InstanceProperty> & {
[key in InstanceProperty]: Instance[InstanceProperty];
};
}
However, when attempting to use this function, I encountered an error:
const unprivate = unsafe_expose(instance, "__someProperty");
// Argument of type '"__someProperty"' is not assignable to parameter of type 'keyof SomeClass'.
This led me to realize that the type constraint for `Type["key"]` is broader than `keyof Type`, and I am wondering if there is a way to access that broader constraint within the TypeScript type system.
This was primarily a theoretical experiment and is not intended for production code at this time, so I would consider "Tl;Dr no it's not possible" to be a valid response.