Releases: Aleph-Alpha/ts-rs
v11.1.0
Today, we're happy to publish a small follow-up to v11.0.1!
This release fixes a nasty build failure when using the format feature.
Note: For those that use the format feature, this release bumps the MSRV to 1.88. We'd have preferred to do this in a major release, but felt this was acceptable since the build was broken by one of the dependencies anyway.
New features
TypeScript enums with #[ts(repr(enum))
#[ts(repr(enum)) instructs ts-rs to generate an enum, instead of a type for your rust enum.
#[derive(TS)]
#[ts(repr(enum))]
enum Role {
User,
Admin,
}
// will generate `export enum Role { "User", "Admin" }`Discriminants are preserved, and you can use the variant's name as discriminant instead using #[ts(repr(enum = name))]
#[ts(optional_fields)] in enums
The #[ts(optional_fields)] attribute can now be applied directly to enums, or even to individual enum variants.
Control over file extensions in imports
Normally, we generate import { Type } from "file" statements. In some scenarios though, it might be necessary to use a .ts or even .js extension instead.
This is now possible by setting the TS_RS_IMPORT_EXTENSION environment variable.
Note: With the introduction of this feature, we deprecate the
import-esmcargo feature. It will be removed in a future major release.
Full changelog
- Regression:
#[ts(optional)]with#[ts(type)]by @NyxCode in #416 - release v11.0.1 by @NyxCode in #417
- Make
rename_allcompatible with tuple and unit structs as a no-op attribute by @gustavo-shigueo in #422 - Replace
import-esmwithTS_RS_IMPORT_EXTENSIONby @gustavo-shigueo in #423 - Updated chrono Duration emitted type by @fxf8 in #434
- Add optional_fields to enum by @gustavo-shigueo in #432
- Add
#[ts(repr(enum)]attribute by @gustavo-shigueo in #425 - Fix build with
formatfeature by @gustavo-shigueo in #438
New Contributors
v11.0.0
We are excited to announce v11.0.0!
Upgrading from v10.x.x
- With the
serde-compatfeature enabled (default), fields annotated with both#[serde(skip_serializing(_if))]and#[serde(default)]are now turned into optional properties.
See "Improved serde compatibility" under "New features" below - The API of the
ts_rs::TStrait has slightly changed.
Some trivial adjustments to your code might be necessary, though only if you interact withts_rs::TSdirectly.
Most users should not be affected by this.
New features
Everything's optional!
With v11, we introduce #[ts(optional_fields)], which can cut down on annoying boilerplace.
This attribute can be applied to structs and has the same effect as adding #[ts(optional)] to every field.
Example:
#[derive(TS)]
#[ts(optional_fields)]
struct Form {
first_name: Option<String>, // first_name?: string
last_name: Option<String>, // last_name?: string
email: Option<String>, // email?: string
}Improved serde compatibility
In the past, #[serde(skip_serializing)] and #[serde(skip_serializing_if = "..")] were ignored by ts-rs.
With v11, we now take these attributes into account, as long as they are used together with #[serde(default)].
This ensures that the generated type is valid for both serializing and deserializing rust structures by default.
A field annotated with #[serde(skip_serializing_(if))] and #[serde(default)] will be treated as if it was annotated with #[ts(optional = nullable)].
This behavior can be overridden using #[ts(optional = false)].
Example:
// now generates `type User = { nickname?: string | null }`,
// making it correct for both serialization and deserialization by default.
#[derive(Serialize, Deserialize, TS)]
struct User {
#[serde(skip_serializing_if = "Option::is_none", default)]
nickname: Option<String>,
}More flexible attributes
#[doc = ..], #[ts(rename = "..")] and #[ts(export_to = "..")] now accept arbitrary expressions!
This enables some cool new patterns and makes integrating ts-rs in unusual setups easier.
Example:
// Renamed to the name of the current module
#[derive(TS)]
#[ts(rename = module_path!().rsplit_once("::").unwrap().1)]
struct Model;
// Comment containing the file path where the type was defined
#[derive(TS)]
#[doc = concat!("Defined in ", file!())]
struct UserGroup { . }Optional tuple structs
The #[ts(optional)] attribute can now also be applied to fields of tuple structs.
Example:
// generates `type Location = [Country, State, City?]`
#[derive(TS)]
struct Location(Country, State, #[ts(optional)] City);Full changelog
- Add
#[ts(optional)]to struct by @gustavo-shigueo in #366 - Add MSRV test to CI by @gustavo-shigueo in #381
- remove lazy_static by @ValiuchenkoVladyslav in #373
- Fix
#[ts(as = "...")]dependency list by @gustavo-shigueo in #385 - Prevent naming collisions with by @gustavo-shigueo in #386
- Handle serde fail gracefully by @gustavo-shigueo in #389
- Merge same path imports by @gustavo-shigueo in #392
- Allow arbitrary expressions in top-level
#[ts(rename)]by @NyxCode in #398 - Allow arbitrary expressions in
#[ts(export_to)]by @NyxCode in #399 - Remove duplicate validation by @gustavo-shigueo in #404
- Allow arbitrary expressions in
#[doc]by @NyxCode in #411 - Allow
#[ts(flatten)]for fields of type HashMap by @gustavo-shigueo in #406 - Handle
serde(skip_serializing_if)+serde(default)by @manifest in #393 - release v11.0.0 by @NyxCode in #413
New Contributors
- @ValiuchenkoVladyslav made their first contribution in #373
- @manifest made their first contribution in #393
v10.1.0
v10.1 is a small follow-up to v10, bringing some bug-fixes and support for tokio.
New Features
- add support for tokio by @joriskleiber in #353 (
tokio-implfeature gate)
Fixes
- feat(serde-json-impl): handle bool for serde_json::Value by @GuillaumeDecMeetsMore in #358
- Include
nullinserde_json::Valueby @NyxCode in #359 - Fix empty struct tagged enum variant by @gustavo-shigueo in #371
- Add
cargo test export_bindingsto README by @dessalines in #363 - Add generated type to README by @gustavo-shigueo in #365
- Fix typo in
#[ts(rename_all_fields)]by @sebastinez in #368
New Contributors
- @GuillaumeDecMeetsMore made their first contribution in #358
- @joriskleiber made their first contribution in #353
- @dessalines made their first contribution in #363
- @sebastinez made their first contribution in #368
New Contributors
- @GuillaumeDecMeetsMore made their first contribution in #358
- @joriskleiber made their first contribution in #353
- @dessalines made their first contribution in #363
- @sebastinez made their first contribution in #368
Full Changelog: v10.0.0...v10.1.0
v10.0.0
While v10.0.0 is a technically breaking change, we expect it to be a drop-in replacement for almost all users.
Changes to HashMap<K, V> (& friends)
In this release, we've changed how HashMap<K, V> is represented in TypeScript.
Before v10, ts-rs generated { [key: K]: V }. This was never technically correct, resulting in tsc accepting some code which it should not have. Additionally, this resulted in issues when e.g trying to use an enum as key.
With v10, we now generate { [key in K]?: V } instead.
What's New?
- Multiple types can be exported to the same file using
#[ts(export_to = "..")] #[ts(as = "..")]and#[ts(type = "..")]now also work on enum variants- Support for more crates (
bson,smol_str)
Full changelog
- Change
HashMapto export mapped types by @gustavo-shigueo in #339 - feat: add bson ObjectId impl by @ShaunSHamilton in #340
- Fix JSDoc formatting for Rust block comments by @gustavo-shigueo in #342
- Fix error in internally tagged enums with flattened fields by @gustavo-shigueo in #344
- feat: Allow multiple types to set
#[ts(export_to = "...")]to the same file by @escritorio-gustavo in #316 - Always use forward slash on import paths by @gustavo-shigueo in #346
- feature: support smol_str by @corvusrabus in #350
- Support
#[ts(as = "...")]and#[ts(type = "...")]on enum variants by @escritorio-gustavo in #284
New Contributors
- @ShaunSHamilton made their first contribution in #340
- @corvusrabus made their first contribution in #350
v9.0.1
v9.0.0
While v9.0.0 is a technically breaking change, we expect it to be a drop-in replacement for almost all users.
Only code interacting with TS::dependency_types and TS::generics will need to be adjusted.
What's new?
Removal of TypeList
The biggest change of v9.0.0 is an internal one: We removed TypeList from the API.
This fixes the long-standing issue of complex types failing to compile with
overflow evaluating the requirementorreached the recursion limit
Even if you did not run into those, we do expect this change to also improve compilation times.
Allow for _ in #[ts(as = "..")]
Similar to how it works in serde, _ can be used in #[ts(as = "..")] to refer to the type of the field.
This is particularly useful for more complex type overrides.
Allow #[ts(as = "..")] and #[ts(type = "..")] on structs and enums
These two attributes can now be used directly on structs and enums.
Previously, it was necessary to add these attributes on every field where the type was used.
This feature is particularly useful for exposing newtypes transparently.
To see a list of all changes, check out CHANGELOG.md!
All changes
- Release 8.1.0 by @NyxCode in #283
- add support for top level type overrides by @dr-bonez in #286
- Fix
#[ts(rename_all_fields = "...")]on enums containing tuple or unit variants by @escritorio-gustavo in #287 - add support for top level
asby @dr-bonez in #288 - Prevent empty
Dependenciesfrom being added todependency_typesby @escritorio-gustavo in #291 - Rework attribute parsing by @escritorio-gustavo in #290
- Add MSRV to cargo.toml and README by @escritorio-gustavo in #300
- Fix race condition in imports test by @escritorio-gustavo in #302
- Fix inconsistencies with
serdeand addSCREAMING-KEBAB-CASEby @escritorio-gustavo in #298 - Support
#[serde(with = "...")]for struct fields by @escritorio-gustavo in #280 - dedup dependencies by @kamadorueda in #293
- Fix location of rename_all errors by @escritorio-gustavo in #303
- Infered types (
_) in#[ts(as = "...")]by @escritorio-gustavo in #299 - Track
Cargo.lockfiles to improve CI speed by @escritorio-gustavo in #295 - Fix #308 by @NyxCode in #309
- Fix missing case in #299 by @escritorio-gustavo in #310
- Coerce passed type to TS before invoking ::name() by @paultag in #318
- Recusion Limit - Round 2 by @NyxCode in #306
- Testing with --no-default-features didnt seem to work in CI by @NyxCode in #319
- Insert newline at end of generated files by @lucperkins in #321
- bug: Fix issue with absolute paths by @escritorio-gustavo in #323
New Contributors
- @dr-bonez made their first contribution in #286
- @kamadorueda made their first contribution in #293
- @paultag made their first contribution in #318
- @lucperkins made their first contribution in #321
Full Changelog: v8.1.0...v9.0.0
v8.1.0
v8.1.0 is a mostly a small follow-up to v8.0.0, fixing a couple of rough edges.
We expect v8.1.0 to be fully compatible to v8.0.0.
Additionally, we've added support for serde_json behind the serde-json-impl cargo feature.
This might seem like a small change, but a lot of work over the past months has now paid off and made cleanly supporting serde_json::Value possible.
Features
- Add
#[ts(crate = "..")]to allow usage of#[derive(TS)]from other proc-macro crates (#274) - Add support types from
serde_jsonbehind cargo featureserde-json-impl(#276) HashMapand similar types are now represented as{ [key: K]: V }instead ofRecord<K, V>(#277)
Fixes
- Macro expansion for types with generic parameters now works without the
TStrait in scope (#281) - Fix flattening a struct that contains a flattened enum (#282)
Full Changelog: v8.0.0...v8.1.0
v8.0.0
After a lot of work and quite some time, we're happy to announce v8.0.0 of ts-rs. 🥳
Migration from 7.x.x
While this is a major release, we do expect that it's drop-in upgrade for most usecases.
However, if your setup is more involved (e.g interacting with the TS trait directly, doing post-processing on the output, etc.), some changes might be necessary.
If you're having any trouble migrating, please feel free to open a discussion or issue, we're happy to help.
Highlights
- Automatic export of dependencies
If a struct or enum is annotated with#[ts(export)], all of its dependencies will be exported automatically, even if they are not annotated with#[ts(export)]. This behaviour is more convenient and always results in correctimportstatements.
More importantly, this enables the use of ts-rs within libraries. Consumers of such a library will automatically get a copy of the types their types depend on. - New handling of generic types
Handling of generic types has been massively improved in this release. Not only is it way more robust than before, but we're also able to support all the edge-cases we couldn't before. For example, structs with trait bounds, generic type aliases and structs containing associated types are all supported now! - Improved handling for enums
Support for enums and their different representations (internally tagged, externally tagged, untagged) has been massively improved in this release, thanks to @escritorio-gustavo!
In all these cases, ts-rs's behaviour matches more or less exactly with that of serde. - Easier exports
Exporting types is now much easier than before. For one, runningcargo testnow exports all dependencies of types annotated with#[ts(export)]. The output directory can now be customized by setting theTS_RS_EXPORT_DIRenvironment variable.
For more complicated setups, where#[ts(export)]is not sufficient, we've reworked the API for exporting types from code.
Acknowledgements
We've had a lot of new contributors since the last release!
I'm also excited to welcome @escritorio-gustavo as a new maintainer, who has been instrumental in making 8.0.0 happen!
Breaking changes
- Export types as
typeinstead ofìnterface(#203) - Automatically export all dependencies when using
#[ts(export)], addTS::dependency_types()(#221) - Remove support for "skip_serializing", "skip_serializing_if" and "skip_deserializing". (#204)
- Initially supporting these by skipping a field was a mistake. If a user wishes to skip a field, they can still
annotate it with#[ts(skip)]
- Initially supporting these by skipping a field was a mistake. If a user wishes to skip a field, they can still
- Added
TS::dependency_types()(#221) - Added
TS::generics()(#241) - Added
TS::WithoutGenerics(#241) - Removed
TS::transparent()(#243) - Handling of output paths (#247, #250, #256)
- All paths specified using
#[ts(export_to = "...")]are now relative toTS_RS_EXPORT_DIR, which defaults to./bindings/
- All paths specified using
- Replace
TS::exportwithTS::export,TS::export_allandTS::export_to_all(#263)
Features
- Implement
#[ts(as = "..")](#174) - For small arrays, generate tuples instead of
Array<T>(#209) - Implement
#[ts(optional = nullable)](#213) - Allow inlining of fields with generic types (#212, #215, #216)
- Allow flattening enum fields (#206)
- Add
semver-implcargo feature with support for the semver crate (#176) - Support
HashMapwith custom hashers (#173) - Add
import-esmcargo feature to import files with a.jsextension (#192) - Implement
#[ts(...)]equivalents for#[serde(tag = "...")],#[serde(tag = "...", content = "...")]and#[serde(untagged)](#227) - Support
#[serde(untagged)]on individual enum variants (#226) - Support for
#[serde(rename_all_fields = "...")](#225) - Export Rust doc comments/attributes on structs/enums as TSDoc strings (#187)
Result,Option,HashMapandVechad their implementations ofTSchanged (#241)- Implement
#[ts(...)]equivalent for#[serde(tag = "...")]being used on a struct with named fields (#244) - Implement
#[ts(concrete(..))]to specify a concrete type for a generic parameter (#264) - Implement
#[ts(bound = "...")]to manually override the generatedwhereclause (#269)
Fixes
- Fix
#[ts(skip)]and#[serde(skip)]in variants of adjacently or internally tagged enums (#231) rename_allwithcamelCaseproduces wrong names if fields were already in camelCase (#198)- Improve support for references (#199)
- Generic type aliases generate correctly (#233)
- Improve compiler errors (#257)
- Update dependencies (#255)
Full Changelog: v7.1.1...v8.0.0