Conversation
d844c2b to
1e489ec
Compare
|
Please also strongly consider using JavaScript naming conventions for 1.0, with a possible exception for the schema definition functions. Specifically, non-types/non-classes would start with a lowercase letter. In ten years of using JavaScript, your library is the only one I've used that violates these conventions. While I absolutely love TypeBox and am integrating it throughout my app, I have to say that this is and continues to be seriously irritating. If you want broader adoption of TypeBox, this may be the most important thing you can do. I experience a huge amount of friction using TypeBox, as my brain is wired to think of uppercase-first identifiers indicate namespaces and types. One of my objectives creating libraries based on TypeBox is to hide this friction and try to make TypeBox more pleasant to use. I have several times debated whether I should be using TypeBox because of this friction. I can't be the only one. Something to consider. |
|
@jtlapp Hey, thanks for the feedback.
It's very unlikely TypeBox would be able to change the Pascal casing used in the library at this point (it's been using this casing for 6 years and I think most developers who use TB seem to be ok with it). It's somewhat of a defining thing about the library at this point, but there are quite a few rationales for opting for Pascal over the more traditional camel casing. The main reason TypeBox opts for it is that types are typically written with Pascal casing (across all languages). The other main reason is that Pascal provides strong visual distinction between variables representing types, and variables representing values (where in JavaScript, everything is a value). JavaScript doesn't really have a convention for expressing these two concepts through casing rules (on account of it not having types), so TypeBox uses Pascal to draw the distinction out. So, these are the main reasons TB uses Pascal. As for JavaScript conventions, I lean more towards the view that conventions should be broken where appropriate, and TypeBox is generally a reflection of this view as the library is addressing domains quite distinct to what most JavaScript libraries would addressing.... Thanks again for feedback! |
|
I did say, "with a possible exception for the schema definition functions," which seems to eliminate your first two points. I'd be happy with initial-lowercase names for non-type functions: Value.check()
Value.create()
Value.clone()
Value.check()
Value.cast()
Value.diff()
etc...I'll wrap any functions that look like types so I'm not dealing with this friction. I bet if you were to poll people, the vast majority would agree with using JavaScript conventions, except for JSON Schema type functions. I'd also bet that your audience is smaller that it could be for creating this friction. Anyway, I'll not argue further, as it's clear that you aren't open to changing naming conventions. |
|
@jtlapp Heya, all good.
Yeah, I have considered possibly using camel casing rules for these, but for the sake of consistency throughout, I've kept them Pascal as well. However it is possible to import each Value API separately as of the last release, so if you are lowercasing them in your code base, you might be able to handle that via import aliases import { Cast as cast } from '@sinclair/typebox/value/cast'
import { Create as create } from '@sinclair/typebox/value/create'
import { Clone as clone } from '@sinclair/typebox/value/clone'
import { Check as check } from '@sinclair/typebox/value/check'Hope that helps, I'll give the casing some more thought as things progress. There has been some consideration moving the Cheers! |
|
That's a bit tedious, but it does help. Thanks for keeping an open mind, after all! |
30d0e28 to
60f4cee
Compare
0.31.0
Overview
Revision 0.31.0 is a subsequent milestone revision for the TypeBox library and a direct continuation of the work carried out in 0.30.0 to optimize and prepare TypeBox for a 1.0 release candidate. This revision implements a new codec system with Transform types, provides configurable error message generation for i18n support, adds a library wide exception type named TypeBoxError and generalizes the Rest type to enable richer composition. This revision also finalizes optimization work to reduce the TypeBox package size.
This revision contains relatively minor breaking changes due to internal type renaming. A minor semver revision is required.
Contents
Transform Types
Revision 0.31.0 includes a new codec system referred to as Transform types. A Transform type is used to augment a regular TypeBox type with Encode and Decode functions. These functions are invoked via the new Encode and Decode functions available on both Value and TypeCompiler modules.
The following shows a Transform type which increments and decrements a number.
Encode and Decode
Revision 0.31.0 includes new functions to Decode and Encode values. These functions are written in service to Transform types, but can be used equally well without them. These functions return a typed value that matches the type being transformed. TypeBox will infer decode and encode differently, yielding the correct type as derived from the codec implementation.
The following shows decoding and encoding between number to Date. Note these functions will throw if the value is invalid.
The Decode function is extremely fast when decoding regular TypeBox types; and TypeBox will by pass codec execution if the type being decoded contains no interior Transforms (and will only use Check). When using Transforms however, these functions may incur a performance penelty due to codecs operating structurally on values using dynamic techniques (as would be the case for applications manually decoding values). As such the Decode design is built to be general and opt in, but not necessarily high performance.
StaticEncode and StaticDecode
Revision 0.31.0 includes new inference types
StaticEncodeandStaticDecode. These types can be used to infer the encoded and decoded states of a Transform as well as regular TypeBox types. These types can be used to replaceStaticforRequestandResponseinference pipelines.The following shows an example
Routefunction that uses Transform inference viaStaticDecode.Rest Types
Revision 0.31.0 updates the Rest type to support variadic tuple extraction from Union, Intersection and Tuple types. Previously the Rest type was limited to Tuple types only, but has been extended to other types to allow uniform remapping without having to extract types from specific schema representations.
The following remaps a Tuple into a Union.
This type can be used to remap Intersect a Composite
Record Key
Revision 0.31.0 updates the inference strategy for Record types and generalizes RecordKey to TSchema. This update aims to help Record types compose better when used with generic functions. The update also removes the overloaded Record factory methods, opting for a full conditional inference path. It also removes the
RecordKeytype which would type error when used with Record overloads. The return type of Record will be TNever if passing an invalid key. Valid Record key types include TNumber, TString, TInteger, TTemplateLiteral, TLiteralString, TLiteralNumber and TUnion.TypeBoxError
Revision 0.31.0 updates all errors thrown by TypeBox to extend the sub type
TypeBoxError. This can be used to help narrow down the source of errors intry/catchblocks.TypeSystemErrorFunction
Revision 0.31.0 adds functionality to remap error messages with the TypeSystemErrorFunction. This function is invoked whenever a validation error is generated in TypeBox. The following is an example of a custom TypeSystemErrorFunction using some of the messages TypeBox generates by default. TypeBox also provides the DefaultErrorFunction which can be used for fallthrough cases.
It is possible to call
.Set()on the TypeSystemErrorFunction module prior to each call to.Errors(). This can be useful for applications that require i18n support in their validation pipelines.Reduce Package Size
Revision 0.31.0 completes a full sweep of code optimizations and modularization to reduce package bundle size. The following table shows the bundle sizes inclusive of the new 0.31.0 functionality against 0.30.0.
Additional code reductions may not be possible without implicating code maintainability. The
typeboxmodule may however be broken down into sub modules in later revisions to further bolster modularity, but is retained as a single file on this revision for historical reasons (not necessarily technical ones).JsonTypeBuilder and JavaScriptTypeBuilder
Revision 0.31.0 renames the
StandardTypeBuilderandExtendedTypeBuildertoJsonTypeBuilderandJavaScriptTypeBuilderrespectively. Applications that extend TypeBox's TypeBuilders will need to update to these names.These builders also update the jsdoc comment to
[Json]and[JavaScript]inline with this new naming convention.TypeSystemPolicy
Revision 0.31.0 moves the
TypeSystem.Policyconfigurations into a new type namedTypeSystemPolicy. This change was done to unify internal policy checks used by the Value and Error modules during bundle size optimization; as well as to keep policy configurations contextually separate from the Type and Format API on the TypeSystem module.