-
Notifications
You must be signed in to change notification settings - Fork 10
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
How to get all TS keywords? #208
Comments
I think all keywords are listed in the SyntaxKind enum inside the type definitions for the TypeScript compiler API. As far as I can tell, they conveniently all have the suffix 'Keyword'. |
@HoldYourWaffle thanks for the tip! However, we also need to include other "keywords", such as utility type Record. See related issue #206 We definitely can extract them from either source code, or type definitions, we just have to compile a full list of such keywords that may conflict with generated interfaces. If you'd like to help with this issue, it would be greatly appreciated :) |
Ah, I see. Since that issue was closed I assumed it was not a problem anymore. However, after some investigation I'm struggling to understand in what situations this would be an issue. As far as I know, this only causes issues if a Google-type wants to access a TypeScript-type that happens to have a Google-type with the same name in the same namespace, which is what happened with #211. As for keywords, I doubt they're going to be an issue. interface MySpecialObject {
property: {
void: string
}
} Lastly, TypeScript only rejects function declarations with a keyword-name if this keyword is also a keyword in plain JS: namespace MySpecialNamespace {
// Perfectly fine, 'namespace' is not a JS keyword
function namespace(): void;
// Definitely not fine, 'while' is a JS keyword
function while(): void;
} These function-names should not exist in However, if my assessment turns out to be incorrect (which wouldn't surprise me given my limited knowledge on this project), I'd definitely want to help pull these 'globals' from the built-in type definitions :) |
Thank you, @HoldYourWaffle, you're absolutely right. The issue was that we were using This means that not everything is fine with this project (yet). Also, our interface AddChartResponse {
/** The newly added chart. */
embedded?Chart?: EmbeddedChart;
} But I'll move this to a separate issue. |
Parsing the AST of the "included" declaration files to pull out global interface names shouldn't be that hard, even though the API can be really intuitive at times. However, I think I have enough (slightly traumatic) experience with the API to make this a not-really-trivial-but-also-not-too-bad task. Assuming we get this list of 'global interfaces', what would we do with it to prevent conflicts? As I mentioned earlier, conflicts only occur if a Google-type references a global-type that has a Google-type with the same name in the same namespace. I'm not a fan of renaming the Google-types, as this would create type references like Unfortunately a |
So far, the policy of preventing such conflicts was simple: inline utility types (as you can see in #211). The one thing that is important to note here, as I suspect that it creates a bit of confusion: we're not getting any code from Google. Meaning, that we will never get something that contains utility types (example). Usage of utility types was totally up to us. So, having a test will prevent us from using utility types ever again, by accident. For example, if someone makes PR that uses utility types, CI will fail, reminding us that they are potentially dangerous, as they may interfere with Google interface names.
Ban all of them from generated types (as a precautionary measure). Banning probably should happen in auto-generate.yml, after types are generated. UPDATE |
I think the only way to avoid carpet-banning utility types would be to generate type definitions in a true module-format, rather than using semi-global namespaces. This would allow us to define type aliases to TypeScripts utility types before a Google's type can hide them, without polluting the global scope. It would also most likely result in nicer import syntax, shorter type references, less confusing usage and less friction when using tooling such as webpack. There is a big downside though: it would be a massive breaking change, the scale varying depending on how we would exactly define these modules. I'll see if I can draft up some ways we could structure the definitions as true modules, preferably with the least amount of 'breakage' possible of course. |
Do you mind elaborating a bit on each of these points?
There's none currently since types are global.
You mean getting rid of
Really interested in what you found confusing. It'll be great if we could make
I didn't use |
Of course not.
My initial thought process went somewhere along the lines of "If we abolish namespaces completely, we could do things like In other words: big dumb from my side.
I guess that's an added benefit.
There's a good chance that this is caused by my setup, but types weren't automatically loaded for me when using Vue single-file-components (which uses webpack). But I think you're right, the types should be global, and I shouldn't need to import them if they are. Yet I had to, although I should probably check if this wasn't caused by some configuration issue on my side.
If I remember correctly (currently melting in a heatwave), I meant two things with 'friction' here:
|
Thank you for your feedback! |
Hello @HoldYourWaffle! It's been a while since the last time we talked :) |
Related to #206
The text was updated successfully, but these errors were encountered: