TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Type-Safe Printf() in TypeScript

94 点作者 wazbug大约 1 年前

12 条评论

jitl大约 1 年前
Word of warning: the typescript compiler is not a particularly fast evaluator of recursive list manipulation programs, which is what these kinds of types are.<p>They’re great in small doses where you really need them, but overuse or widespread use of complex types will make your build slower. It’s much better to avoid generics or mapped types if you can. The typings for a tagged template literal (without digit format specifiers like %d4) don’t require any generics.<p>I love to write code like this, but I’m guilty of over using fancy types and I flinch when I see a typescript build profile showing 45s+ spent on generic types I wrote without realizing the cost.
评论 #39810016 未加载
评论 #39809069 未加载
eyelidlessness大约 1 年前
Minor nit: I’ve found types like these—that is, iterative recursive types—benefit from using terminology common to map&#x2F;reduce. And by “benefit from”, I mean become more understandable by a wider audience—not necessarily the HN audience per se, but quite likely teammates and future selves.<p>Which is to say, these names almost always make types like this more clear:<p>- Head: the first item in the input type you’re iterating through<p>- Tail: the remaining items or unprocessed structure you’ll likely recurse on next<p>- Acc (or pick your favorite “reduced” idiom): a named type for the intermediate product which will become the final type when you finish iterating. This can be provided as an optional parameter with an empty tuple as its default, largely modeling a typical reduce (apart from inverting the common parameter order).<p>It also helps, IME, to put a “base case” first in the type’s conditions.<p>When all of these names and patterns are utilized, the resulting type tends to look quite a lot like an equivalent runtime function you could encounter for producing the value equivalent to its type. This is great because you can even write the runtime function to match the type’s logic. This demonstrates both what the type is doing for people who find these “complex types” intimidating, and that the type accurately describes the value it’s associated with.
评论 #39808871 未加载
IceDane大约 1 年前
Cool.<p>There is a way to make this easier to extend, though: <a href="https:&#x2F;&#x2F;tsplay.dev&#x2F;WGbEXm" rel="nofollow">https:&#x2F;&#x2F;tsplay.dev&#x2F;WGbEXm</a><p>Can&#x27;t tell off the top of my head if there are any disadvantages to this approach though.
crgwbr大约 1 年前
Neat, but this is basically a ripoff of this post from a few years ago (even to the point of not including the runtime implementation):<p><a href="https:&#x2F;&#x2F;www.hacklewayne.com&#x2F;a-truly-strongly-typed-printf-in-typescript" rel="nofollow">https:&#x2F;&#x2F;www.hacklewayne.com&#x2F;a-truly-strongly-typed-printf-in...</a>
pkkm大约 1 年前
Reminds me of Idris: <a href="https:&#x2F;&#x2F;gist.github.com&#x2F;chrisdone&#x2F;672efcd784528b7d0b7e17ad9c115292" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;chrisdone&#x2F;672efcd784528b7d0b7e17ad9c...</a><p>Recently though, I&#x27;ve been wondering whether advanced type system stuff is the right approach. It usually becomes pretty complicated, like another language on top of the regular language. Maybe it would be easier to have some kind of framework for compiler plugins that do extra checks. Something that would make it easy to check format strings or enforce rules on custom attributes, like Linux&#x27;s sparse does, using plain imperative code that&#x27;s readable to the average dev. Large projects would have an extra directory for compile time checks in addition to the tests directory they have now.<p>But I haven&#x27;t seen any language community do something like that. What am I missing?
评论 #39808810 未加载
评论 #39808338 未加载
评论 #39808482 未加载
评论 #39808635 未加载
评论 #39810526 未加载
评论 #39810795 未加载
yen223大约 1 年前
The interesting thing here is that the typesafe printf has its function arguments inferred from a string literal, at compile time. You can change the 9 to a &quot;9&quot; and see the type error even before running the code.<p>This is something that most mainstream language&#x27;s type system cannot do.<p>(This may be obvious, but a lot of commenters here might have missed that.)
ruined大约 1 年前
not sure i understand the utility of this when format strings and string template types already exist.<p>you can also use <i>typescript-eslint&#x2F;restrict-template-expressions</i> if you find yourself running into problems with that<p><a href="https:&#x2F;&#x2F;typescript-eslint.io&#x2F;rules&#x2F;restrict-template-expressions&#x2F;" rel="nofollow">https:&#x2F;&#x2F;typescript-eslint.io&#x2F;rules&#x2F;restrict-template-express...</a>
评论 #39808677 未加载
taeric大约 1 年前
I&#x27;ve been kind of curious why tricks like this aren&#x27;t used more to make sql and such. Heck, you could do similar tricks for shell execution. Or any general &quot;string that is parseable.&quot; Seems we always take the route of not parsing the string as much as we can?
评论 #39808979 未加载
评论 #39810587 未加载
评论 #39809325 未加载
评论 #39809034 未加载
评论 #39809568 未加载
评论 #39808836 未加载
akira2501大约 1 年前
Am I missing something? This is just a toy implementation of a function prototype, that only includes integers and strings?
评论 #39809418 未加载
k__大约 1 年前
Nice!<p>Now do ReScript. :D
beders大约 1 年前
Honestly, if you spend that much code on a single `printf`, I will reject your PR and we will have a conversation about code maintenance and cost.<p>Please don&#x27;t adopt this.
评论 #39811151 未加载
Touche大约 1 年前
Except missing the pesky runtime implementation. We don&#x27;t need though, right? As long as the types say it&#x27;s right.
评论 #39808074 未加载
评论 #39808318 未加载
评论 #39808065 未加载