You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
DashCase and CamelCase intrinsic string types, or similar #40710
It would be great to also have DashCase and CamelCase and similar!
Use Cases
It is common in DOM libs to map from JS camelCase properties to DOM dash-case attributes (f.e. el.fooBar = 123 and <el foo-bar="123">), or CapitalizedClass names to dash-case custom element names (f.e. class FooBar extends HTMLElement and <foo-bar>).
Something that’s important to clarify in this suggestion is whether it’s important that these types be intrinsic or if you just want some solution built into lib.d.ts. Various comments in #40336 demonstrate that these transformations are already possible, but are complex to write. If they were written into lib.d.ts, but were not intrinsics, would that be a good solution, or would there be performance / depth limit issues?
Type Camelcase could take an optional initialism union a la github.com/golang/lint but overall I think this will be a useful standard lib intrinsic.
If there's no consensus on a standard I don't know how typescript plans to regulate custom intrinsic implementations... would they be fishable like node_modules/@types? It would probably never end up in the standard lib but a jsonschema validator would be a favorite of mine.
functionmockingly<Sextendsstring>(s: S): intrinsic{returns.split('').map((c,i)=>c[i%2 ? 'toUpperCase' : 'toLowerCase']().join(' ')}Expect<typeofmockingly("hello world"),"H e L l O W o R l D">
Wouldn't e.g. a graphql schema parser be unoptimized written as a type and have concerns about recursion depth?
Yes, absolutely. We would not recommend you do that either! 😄
Right now graphql-codegen works
Great, problem solved! Preprocessing is our recommendation for this kind of problem in general. We’re not interested in performing arbitrary code execution during compile time. (At any rate, this discussion is off-topic for this issue, which is asking us to add new instrinsics ourselves.)
Personally standard lib or intrinsic is fine for me as someone who will simply use it. I'll leave it to the TS experts what's better. From my point of view as an end user, lib.d.ts and actual intrinsics are all "intrinsic" in the end-user sense: built-in types that I get to use.
I instead toyed with the idea of a general Split<K, "-">with which one could implement a CamelCase or DashCase oneself: sindresorhus/meow#155 (comment)
I think Split<> has to be intrinsic, but I don't think either of CamelCase or KebabCase (isn't that the more common name for DashCase?) has to be intrinsic.
Actually, scratch that, as shown in the top description of #40336, a Split<> doesn't have to be intrinsic at all but is actually possible right now in the current nightly and with that comes the creation of eg. CamelCase<>.
Trick is to use infer within the template string literal, like:
Pelle Wessman (@voxpelli) great work! The only thing I would point out is that the implementation in your latest linked playground cannot properly handle strings which start with a separator or have multiple separators side by side. Example:
Ken Powers (@knpwrs) your solution kills the playground tab in my browser (and the TS language service in my VSC 😅 ) when I use the following keys:
'Awa_bbb-ccc' | '-Awa_bbb-ccc' | '_Awa_bbb-ccc'
I came up with my own implementation and it seems to be working better for strings up to 15 characters long. Unfortunately anything longer than that triggers the
Type instantiation is excessively deep and possibly infinite.ts(2589)
Is there any interest in making it possible to write custom intrinsic string types? For popular libraries like Material UI, it would be really helpful (i.e. below):
Pelle Wessman (@voxpelli) thx for the good work. Your implementation works only If word has only two segments. I upgraded it to work with an endless number of segments
Activity
andrewbranch commentedon Sep 23, 2020
Something that’s important to clarify in this suggestion is whether it’s important that these types be intrinsic or if you just want some solution built into lib.d.ts. Various comments in #40336 demonstrate that these transformations are already possible, but are complex to write. If they were written into
lib.d.ts, but were not intrinsics, would that be a good solution, or would there be performance / depth limit issues?mmmveggies commentedon Oct 2, 2020
Type
Camelcasecould take an optional initialism union a la github.com/golang/lint but overall I think this will be a useful standard lib intrinsic.If there's no consensus on a standard I don't know how typescript plans to regulate custom intrinsic implementations... would they be fishable like
node_modules/@types? It would probably never end up in the standard lib but a jsonschema validator would be a favorite of mine.Also I am on team
KebabCase>DashCaseandrewbranch commentedon Oct 2, 2020
We don’t plan to allow custom intrinsic implementations.
mmmveggies commentedon Oct 2, 2020
Andrew Branch (@andrewbranch) why not? Wouldn't e.g. a graphql schema parser be unoptimized written as a type and have concerns about recursion depth? Right now
graphql-codegenworks but at the very least a non-async pure function seems stable enough.andrewbranch commentedon Oct 2, 2020
Yes, absolutely. We would not recommend you do that either! 😄
Great, problem solved! Preprocessing is our recommendation for this kind of problem in general. We’re not interested in performing arbitrary code execution during compile time. (At any rate, this discussion is off-topic for this issue, which is asking us to add new instrinsics ourselves.)
trusktr commentedon Oct 14, 2020
Personally standard lib or intrinsic is fine for me as someone who will simply use it. I'll leave it to the TS experts what's better. From my point of view as an end user, lib.d.ts and actual intrinsics are all "intrinsic" in the end-user sense: built-in types that I get to use.
voxpelli commentedon Oct 29, 2020
I instead toyed with the idea of a general
Split<K, "-">with which one could implement aCamelCaseorDashCaseoneself: sindresorhus/meow#155 (comment)Enabling something like:
I think
Split<>has to beintrinsic, but I don't think either ofCamelCaseorKebabCase(isn't that the more common name forDashCase?) has to beintrinsic.voxpelli commentedon Oct 29, 2020
Actually, scratch that, as shown in the top description of #40336, a
Split<>doesn't have to be intrinsic at all but is actually possible right now in the current nightly and with that comes the creation of eg.CamelCase<>.Trick is to use
inferwithin the template string literal, like:I made a test on the playground which I'm pasting here:
voxpelli commentedon Oct 29, 2020
Sorry for spamming, but just wanted to add an implementation of
DashCase/KebabCaseas well. See this updated playground.It's a bit more awkward as it eg. as to split on all A-Z uppercase chars as well:
knpwrs commentedon Nov 23, 2020
Pelle Wessman (@voxpelli) great work! The only thing I would point out is that the implementation in your latest linked playground cannot properly handle strings which start with a separator or have multiple separators side by side. Example:
See this updated playground.
I was working on my own
CamelCaseutility type as well. It handles those cases, but it's far less generic than what you've come up with.See this playground.
kdmadej commentedon Feb 12, 2021
Ken Powers (@knpwrs) your solution kills the playground tab in my browser (and the TS language service in my VSC 😅 ) when I use the following keys:
I came up with my own implementation and it seems to be working better for strings up to 15 characters long. Unfortunately anything longer than that triggers the
error 😞 (but doesn't kill the IDE 😅 )
playground link
trusktr commentedon Feb 16, 2021
Pelle Wessman (@voxpelli) Your solution has been working super great, but today I ran into a weird one. Based on your code, I tried this:
And the resulting
testtype isplayground link (see at the bottom)
Anyone know why that happens with that particular example?
trusktr commentedon Feb 16, 2021
Ken Powers (@knpwrs) Expanding on your example, what would the opposite
SnakeCasedPropstype look like?voxpelli commentedon Feb 16, 2021
Joe Pea (@trusktr) Is the same issue happening with the version of it that we're maintaining in https://github.com/sindresorhus/type-fest ?
grumpyTofu commentedon Oct 13, 2021
Is there any interest in making it possible to write custom intrinsic string types? For popular libraries like Material UI, it would be really helpful (i.e. below):
Or perhaps a Typescript guru would be able to come up with a hack for this that is eluding me?
voxpelli commentedon Oct 13, 2021
GrumpyTofu (@grumpyTofu) See these types: https://github.com/sindresorhus/type-fest#template-literal-types
michalica commentedon Apr 8, 2024
Pelle Wessman (@voxpelli) thx for the good work. Your implementation works only If word has only two segments. I upgraded it to work with an endless number of segments
voxpelli commentedon Apr 8, 2024
michalica 👍 You can find the latest iteration of mine in the
type-festmodule, and PR:s are welcome there 😊