-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No IntelliSense with const assertions #41247
Comments
That would be a breaking change. |
It seems like you need #7481. Changing type annotations as suggested would be a cataclysmic breaking change; that's not happening. |
@RyanCavanaugh Thanks for your answer. It's not clear to me how #7481 would solve my issue, but I believe you.
Note it is just one possible solution I suggested (being very unaware of compiler details). But the real issue is that |
However I don't agree with the "Working as intended" flag. That the current syntax works like this and can't change, OK, but that |
Something like |
The type is the type; what you're proposing would be that IntelliSense would operate on something other than the type -- some side channel -- but that would be very out of scope. #7481 is what because you're basically trying to verify that the expression matches |
When doing this: this.storage.get('key', { type: 'string'; enum: ['hello', 'world']; } as const); given that the function signature is: get(key: string, schema: JSONSchema) {} we do have both IntelliSense and the type asserted as I already thought about the workaround solution mentioned in #7481, ie. having an utility function like this: function asType<T extends JSONSchema>(value: T): T {
return value;
} Issue is: it doesn't work with const schema = asType({ type: 'string' }) as const; is not allowed and errors with:
|
Is this the function definition you are talking about? If so I think something like this is more what you would be wanting to do: get<T extends JSONSchema>(key: string, schema: T): ... If you want I can probably help you come up with the right typing for you're case. If you could provide a minimal playground or sandbox that declares the function and a few examples of how you want the way you want to call it that demonstrate the issue you are having, I'd be happy to help. |
@RebeccaStevens Thanks. The function definition you quoted is the current one, which is a mess of overloads because inferring the TS type from a JSON schema was not possible before. The new one is here, and it is indeed like the example you gave: get<Schema extends JSONSchema>(key: string, schema: Schema) {
return ... as InferFromJSONSchema<Schema>;
} It is strongly related to the For Which leads to the situation I explained in the first message of this issue, ie. doing this: this.storage.get('key', { type: 'string' } as const); works and provides autocompletion. But as the same JSON schema must be reused in the const schema = { type: 'string' } as const;
this.storage.set('key', schema);
this.storage.get('key', schema); works but do not provide autocompletion when writing the JSON schema, while: const schema: JSONSchema = { type: 'string' } as const;
this.storage.set('key', schema);
this.storage.get('key', schema); provides autocompletion but fails, as |
I have an architectural question. Why does the schema need to be provided to Back to the current issue at hand. What is the autocompletion supposed to take place on? and what fails? |
The schema is not global to the whole storage, there is one schema for each key. I am thinking of a new API where all possible keys and schemas would be prepared in advance, but that may be even more challenging on the TypeScript side (because the lib user would need to pass the whole config object to Angular, and I would need to infer the TS types of all this config without requiring from the lib user to describe the whole config again in TS types).
In your codesandbox, try to add
When For example with the JSON schema const schema2 = { type: 'string', enum: ['hello', 'world'] } as const; passed to While: const schema1: JSONSchema = { type: 'string', enum: ['hello', 'world'] }; passed to I gave the I'll do a sandbox tomorrow if my explanations are not enough. |
After a proof of concept, I will be able to avoid this issue by unrelated changes in my lib. While I think it is a real issue that I won't be alone to face, and that it will be more and more common (as |
Search Terms
const assertion
Suggestion
Solutions:
schema
should keep the exact type inferred byas const
, and not be widened back toJSONSchema
,as const
while using a type to enable autocompletion.Use Cases
My library (>15K weekly downloads) manages client-side storage, where data is validated at runtime via a JSON schema, so the API is basically:
Given the nature of JSON Schema structure, simplified in the example above, some cases require
as const
assertion to correctly infer types (for example theenum
values).When doing as below, autocompletion is available for the schema:
But as the same schema must be used with
.set()
, a variable is required to store it, and now there will be no autocompletion at all (which is normal):Unfortunately, trying to resolve this scenario by adding an explicit type adds back autocompletion, but also widen back the schema type (as if there was no
as const
assertion):So currently, I'm forced to lose autocompletion if I want to implement this feature: cyrilletuzi/angular-async-local-storage#477
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: