Open Andarist opened 2 years ago
@deprecated
seems pretty close?
Thank you for the suggestion - it's indeed "pretty close" and I didn't think about using this (didn't actually realize that this would put them on the bottom of the suggestions list).
I think there is still potential in the original request though as "pretty close" is not the same. For the time being, I will use the suggested workaround (PR) but I would love it if I could just hide those properties in the future altogether.
Is there any news on this?
need this
need this for what?
I came across a bootstrapping problem that would greatly benefit from having this functionality:
// Represents a type in my database schema. Needs to be fully functional before any initialization
// has taken place. Notably, the decorated properties are *not* accessible before initialization,
// so I need to provide a duplicate set of manually implemented property getters/setters.
// These need to be publicly accessible but should be hidden from the completions list.
@DbType()
class Type {
// Name of the type - not available during initialization, but required for initialization.
@DbProperty({ type: String })
accessor name: String;
// Bootstrapping property to use in place of `name` during initialization.
// Needs to be public (because it is accessed outside of the class) but should be
// hidden from the completions list.
/** @internal @hidden ... @whatever? */
get __name(): String {
return this.manuallyRead("name");
}
set __name(value: String) {
this.manuallyWrite("name", value);
}
}
Regarding the use of @deprecated
, I suppose it works in a pinch, but it doesn't accurately describe the status of the __name
property above.
This would be great for Valibot. We have an internal ._run
property that I want to hide (or move down) and a ._types
property that just stores type information but is never actually assigned at runtime.
https://github.com/fabian-hiller/valibot/blob/v0.36.0/library/src/types/schema.ts#L50-L59
For the use case in the original motivating example, I've been using symbols for this. I don't know if there are any downsides to this approach.
declare const phantom: unique symbol;
type Phantom = typeof phantom;
type Demo<T> = {
[phantom]: T;
value: T;
}
declare const demoValue: Demo<'test'>;
type DemoPhantom = (typeof demoValue)[Phantom];
// ^?
need this for what?
let's say I have a property that I know exists but should not be used somewhere else, it's like private but without the classes.
let's say I have a property that I know exists but should not be used somewhere else, it's like private but without the classes.
You can expose the object as a type that does not include the property, or mark the property as deprecated, or use a convention like underscore prefix, or use a symbol key. Perhaps a more specific example?
let's say I have a property that I know exists but should not be used somewhere else, it's like private but without the classes.
You can expose the object as a type that does not include the property, or mark the property as deprecated, or use a convention like underscore prefix, or use a symbol key. Perhaps a more specific example?
I have a function that recursively calls itself when it fails, because it recursively calls itself, I don't want it to run some functions again and use the previous result,
downloadFile(opts: {
// this should be private
hash: number
}) {
const hash = opts.hash || createHash();
// fails
return downloadFile({ hash })
}
I should not be able to use hash when calling this function elsewhere, I guess symbols could work, deprecated is a bit ehh, idk why private shouldn't work for object types
The example still seems incomplete. You have a function that accepts a parameter that has a property that you intend to use but you want that property to be undocumented or hidden. Do you want the hash
property to be visible only to that function? How is the caller then able to know he is providing a valid argument?
Assuming that hash
is meant to be a "private" property only visible to certain "friend" functions, typing the object with a public interface that omits the property and then using type assertions inside the friend function seems like the appropriate and idiomatic approach.
I'd be all for private
in object literals, but I would expect private member access to be limited to the literal's lexical scope. That wouldn't satisfy this use case.
I should not be able to use hash when calling this function elsewhere
Sorry, missed this bit. So your example makes sense, but the rest of my response applies.
Suggestion
π Search Terms
List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
hide, private, internal, completions
The closest issue found was this but while its title suggests that it may be related - its content seems to be entirely different.
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
It would be cool if I could annotate a member property as being "hidden" and effectively hide it from the completions list.
π Motivating Example
I've found out that extracting type params using a conditional type doesn't always behave the same way as getting that type from a property member.
When it comes to inference we might get different results from signatures resembling those ones:
Obviously, my situation at hand is far more complicated. All type params are actually used, it's possible to extract the generic using a conditional type but when we call
useMachine
with the "concrete" machine then it fails to retrieve the embedded type using the first technique.I've accidentally figured out that the latter improved the situation for us. I've seen this technique to be called in the past "phantom types". Obviously, though, we don't our users to access such a phantom property - it's merely used to help us out with the inference at the consuming call site. So it would be quite cool if we could just annotate those properties somehow so they could be removed from the completions list.
I'm pretty sure that this is such a generic feature that it could be useful to people in more contexts. For instance, in
react-navigation
we might find this beauty: https://github.com/react-navigation/react-navigation/blob/90874397e653a6db642822bff18014a3e5980fed/packages/core/src/types.tsx#L156-L168I've tested out all of the JSdoc tags~ that I could think of but none of them work like that: TS playground
It seem to me though that
@ptivate
/@access private
should actually work as I've found some comments~ in the TypeScript codebase that private properties should be excluded. I see how JSDoc annotation is different from a "real" private property but it would be great if this could "just work".I'm not sure how feasible implementing this is but maybe I could take a crack at this - it seems that the required changes would be limited to
isValidPropertyAccessForCompletions
π» Use Cases
It got kinda covered in the previous section.