pub trait TS {
type WithoutGenerics: TS + ?Sized;
type OptionInnerType: ?Sized;
Show 14 methods
// Required methods
fn name(cfg: &Config) -> String;
fn inline(cfg: &Config) -> String;
// Provided methods
fn docs() -> Option<String> { ... }
fn ident(cfg: &Config) -> String { ... }
fn decl(cfg: &Config) -> String { ... }
fn decl_concrete(cfg: &Config) -> String { ... }
fn inline_flattened(cfg: &Config) -> String { ... }
fn visit_dependencies(_: &mut impl TypeVisitor)
where Self: 'static { ... }
fn visit_generics(_: &mut impl TypeVisitor)
where Self: 'static { ... }
fn dependencies(cfg: &Config) -> Vec<Dependency>
where Self: 'static { ... }
fn export(cfg: &Config) -> Result<(), ExportError>
where Self: 'static { ... }
fn export_all(cfg: &Config) -> Result<(), ExportError>
where Self: 'static { ... }
fn export_to_string(cfg: &Config) -> Result<String, ExportError>
where Self: 'static { ... }
fn output_path() -> Option<PathBuf> { ... }
}Expand description
A type which can be represented in TypeScript. Most of the time, you’d want to derive this trait instead of implementing it manually. ts-rs comes with implementations for all primitives, most collections, tuples, arrays and containers.
§exporting
Because Rusts procedural macros are evaluated before other compilation steps, TypeScript bindings cannot be exported during compile time.
Bindings can be exported within a test, which ts-rs generates for you by adding #[ts(export)]
to a type you wish to export to a file.
When cargo test is run, all types annotated with #[ts(export)] and all of their
dependencies will be written to TS_RS_EXPORT_DIR, or ./bindings by default.
For each individual type, path and filename within the output directory can be changed using
#[ts(export_to = "...")]. By default, the filename will be derived from the name of the type.
If, for some reason, you need to do this during runtime or cannot use #[ts(export)], bindings
can be exported manually using TS::export_all, TS::export, or TS::export_to_string.
§serde compatibility
With the serde-compat feature enabled (default), ts-rs parses serde attributes and adjusts the generated typescript bindings accordingly.
Not all serde attributes are supported yet - if you use an unsupported attribute, you’ll see a
warning. These warnings can be disabled by enabling the no-serde-warnings cargo feature.
§container attributes
attributes applicable for both structs and enums
-
#[ts(crate = "..")]
Generates code which references the module passed to it instead of defaulting to::ts_rsThis is useful for cases where you have to re-export the crate. -
#[ts(export)]
Generates a test which will export the type, by default tobindings/<name>.tswhen runningcargo test. The default base directory can be overridden with theTS_RS_EXPORT_DIRenvironment variable. Adding the variable to a project’s config.toml can make it easier to manage.# <project-root>/.cargo/config.toml [env] TS_RS_EXPORT_DIR = { value = "<OVERRIDE_DIR>", relative = true } -
#[ts(export_to = "..")]
Specifies where the type should be exported to. Defaults to<name>.ts. The path given to theexport_toattribute is relative to theTS_RS_EXPORT_DIRenvironment variable, or, ifTS_RS_EXPORT_DIRis not set, to./bindingsIf the provided path ends in a trailing/, it is interpreted as a directory. This attribute also accepts arbitrary expressions. Note that you need to add theexportattribute as well, in order to generate a test which exports the type. -
#[ts(as = "..")]
Overrides the type used in Typescript, using the provided Rust type instead.
This is useful when you have a custom serializer and deserializer and don’t want to implementTSmanually -
#[ts(type = "..")]
Overrides the type used in TypeScript.
This is useful when you have a custom serializer and deserializer and don’t want to implementTSmanually -
#[ts(rename = "..")]
Sets the typescript name of the generated type.
Also accepts expressions, e.g#[ts(rename = module_path!().rsplit_once("::").unwrap().1)]. -
#[ts(rename_all = "..")]
Rename all fields/variants of the type.
Valid values arelowercase,UPPERCASE,camelCase,snake_case,PascalCase,SCREAMING_SNAKE_CASE, “kebab-case” and “SCREAMING-KEBAB-CASE” -
#[ts(concrete(..)]
Disables one ore more generic type parameters by specifying a concrete type for them.
The resulting TypeScript definition will not be generic over these parameters and will use the provided type instead.
This is especially useful for generic types containing associated types. Since TypeScript does not have an equivalent construct to associated types, we cannot generate a generic definition for them. Using#[ts(concrete(..)], we can however generate a non-generic definition.
Example:#[derive(TS)] #[ts(concrete(I = std::vec::IntoIter<String>))] struct SearchResult<I: Iterator>(Vec<I::Item>); // will always generate `type SearchResult = Array<String>`. -
#[ts(bound)]
Override the bounds generated on theTSimplementation for this type. This is useful in combination with#[ts(concrete)], when the type’s generic parameters aren’t directly used in a field or variant.Example:
trait Container { type Value: TS; } struct MyContainer; #[derive(TS)] struct MyValue; impl Container for MyContainer { type Value = MyValue; } #[derive(TS)] #[ts(export, concrete(C = MyContainer))] struct Inner<C: Container> { value: C::Value, } #[derive(TS)] // Without `#[ts(bound)]`, `#[derive(TS)]` would generate an unnecessary // `C: TS` bound #[ts(export, concrete(C = MyContainer), bound = "C::Value: TS")] struct Outer<C: Container> { inner: Inner<C>, }
§struct attributes
-
#[ts(tag = "..")]
Include the structs name (or value of#[ts(rename = "..")]) as a field with the given key. -
#[ts(optional_fields)]
Makes allOption<T>fields in a struct optional.
If#[ts(optional_fields)]is present,t?: Tis generated for everyOption<T>field of the struct. If#[ts(optional_fields = nullable)]is present,t?: T | nullis generated for everyOption<T>field of the struct.
§struct field attributes
-
#[ts(type = "..")]
Overrides the type used in TypeScript.
This is useful when there’s a type for which you cannot deriveTS. -
#[ts(as = "..")]
Overrides the type of the annotated field, using the provided Rust type instead.
This is useful when there’s a type for which you cannot deriveTS._may be used to refer to the type of the field, e.g#[ts(as = "Option<_>")]. -
#[ts(rename = "..")]
Renames this field. To rename all fields of a struct, see the container attribute#[ts(rename_all = "..")]. -
#[ts(inline)]
Inlines the type of this field, replacing its name with its definition. -
#[ts(skip)]
Skips this field, omitting it from the generated TypeScript type. -
#[ts(optional)]
May be applied on a struct field of typeOption<T>. By default, such a field would turn intot: T | null.
If#[ts(optional)]is present,t?: Tis generated instead. If#[ts(optional = nullable)]is present,t?: T | nullis generated.#[ts(optional = false)]can override the behaviour for this field if#[ts(optional_fields)]is present on the struct itself. -
#[ts(flatten)]
Flatten this field, inlining all the keys of the field’s type into its parent.
§enum attributes
-
#[ts(tag = "..")]
Changes the representation of the enum to store its tag in a separate field.
See the serde docs for more information. -
#[ts(content = "..")]
Changes the representation of the enum to store its content in a separate field.
See the serde docs for more information. -
#[ts(untagged)]
Changes the representation of the enum to not include its tag.
See the serde docs for more information. -
#[ts(rename_all = "..")]
Rename all variants of this enum.
Valid values arelowercase,UPPERCASE,camelCase,snake_case,PascalCase,SCREAMING_SNAKE_CASE, “kebab-case” and “SCREAMING-KEBAB-CASE” -
#[ts(rename_all_fields = "..")]
Renames the fields of all the struct variants of this enum. This is equivalent to using#[ts(rename_all = "..")]on all of the enum’s variants. Valid values arelowercase,UPPERCASE,camelCase,snake_case,PascalCase,SCREAMING_SNAKE_CASE, “kebab-case” and “SCREAMING-KEBAB-CASE” -
#[ts(repr(enum))]
Exports the enum as a TypeScript enum instead of type union.
Discriminants (= {integer}) are included in the exported enum’s variants If#[ts(repr(enum = name))]is used, all variants without a discriminant will be exported asVariantName = "VariantName"
§enum variant attributes
-
#[ts(rename = "..")]
Renames this variant. To rename all variants of an enum, see the container attribute#[ts(rename_all = "..")]. This attribute also accepts expressions, e.g#[ts(rename = module_path!().rsplit_once("::").unwrap().1)]. -
#[ts(skip)]
Skip this variant, omitting it from the generated TypeScript type. -
#[ts(untagged)]
Changes this variant to be treated as if the enum was untagged, regardless of the enum’s tag and content attributes -
#[ts(rename_all = "..")]
Renames all the fields of a struct variant.
Valid values arelowercase,UPPERCASE,camelCase,snake_case,PascalCase,SCREAMING_SNAKE_CASE, “kebab-case” and “SCREAMING-KEBAB-CASE”
Required Associated Types§
Sourcetype WithoutGenerics: TS + ?Sized
type WithoutGenerics: TS + ?Sized
If this type does not have generic parameters, then WithoutGenerics should just be Self.
If the type does have generic parameters, then all generic parameters must be replaced with
a dummy type, e.g ts_rs::Dummy or ().
The only requirement for these dummy types is that EXPORT_TO must be None.
§Example:
use ts_rs::TS;
struct GenericType<A, B>(A, B);
impl<A, B> TS for GenericType<A, B> {
type WithoutGenerics = GenericType<ts_rs::Dummy, ts_rs::Dummy>;
type OptionInnerType = Self;
// ...
}Sourcetype OptionInnerType: ?Sized
type OptionInnerType: ?Sized
If the implementing type is std::option::Option<T>, then this associated type is set to T.
All other implementations of TS should set this type to Self instead.
Required Methods§
Provided Methods§
Sourcefn docs() -> Option<String>
fn docs() -> Option<String>
JSDoc comment to describe this type in TypeScript - when TS is derived, docs are
automatically read from your doc comments or #[doc = ".."] attributes
Sourcefn decl(cfg: &Config) -> String
fn decl(cfg: &Config) -> String
Declaration of this type, e.g. type User = { user_id: number, ... }.
This function will panic if the type has no declaration.
If this type is generic, then all provided generic parameters will be swapped for
placeholders, resulting in a generic typescript definition.
Both SomeType::<i32>::decl() and SomeType::<String>::decl() will therefore result in
the same TypeScript declaration type SomeType<A> = ....
Sourcefn decl_concrete(cfg: &Config) -> String
fn decl_concrete(cfg: &Config) -> String
Declaration of this type using the supplied generic arguments.
The resulting TypeScript definition will not be generic. For that, see TS::decl().
If this type is not generic, then this function is equivalent to TS::decl().
Sourcefn inline_flattened(cfg: &Config) -> String
fn inline_flattened(cfg: &Config) -> String
Flatten a type declaration. This function will panic if the type cannot be flattened.
Sourcefn visit_dependencies(_: &mut impl TypeVisitor)where
Self: 'static,
fn visit_dependencies(_: &mut impl TypeVisitor)where
Self: 'static,
Iterates over all dependency of this type.
Sourcefn visit_generics(_: &mut impl TypeVisitor)where
Self: 'static,
fn visit_generics(_: &mut impl TypeVisitor)where
Self: 'static,
Iterates over all type parameters of this type.
Sourcefn dependencies(cfg: &Config) -> Vec<Dependency>where
Self: 'static,
fn dependencies(cfg: &Config) -> Vec<Dependency>where
Self: 'static,
Resolves all dependencies of this type recursively.
Sourcefn export(cfg: &Config) -> Result<(), ExportError>where
Self: 'static,
fn export(cfg: &Config) -> Result<(), ExportError>where
Self: 'static,
Manually export this type to the filesystem.
To export this type together with all of its dependencies, use TS::export_all.
§Automatic Exporting
Types annotated with #[ts(export)], together with all of their dependencies, will be
exported automatically whenever cargo test is run.
In that case, there is no need to manually call this function.
To alter the filename or path of the type within the target directory,
use #[ts(export_to = "...")].
Sourcefn export_all(cfg: &Config) -> Result<(), ExportError>where
Self: 'static,
fn export_all(cfg: &Config) -> Result<(), ExportError>where
Self: 'static,
Manually export this type to the filesystem, together with all of its dependencies.
To export only this type, without its dependencies, use TS::export.
§Automatic Exporting
Types annotated with #[ts(export)], together with all of their dependencies, will be
exported automatically whenever cargo test is run.
In that case, there is no need to manually call this function.
To alter the filenames or paths of the types within the target directory,
use #[ts(export_to = "...")].
Sourcefn export_to_string(cfg: &Config) -> Result<String, ExportError>where
Self: 'static,
fn export_to_string(cfg: &Config) -> Result<String, ExportError>where
Self: 'static,
Manually generate bindings for this type, returning a String.
This function does not format the output, even if the format feature is enabled.
§Automatic Exporting
Types annotated with #[ts(export)], together with all of their dependencies, will be
exported automatically whenever cargo test is run.
In that case, there is no need to manually call this function.
Sourcefn output_path() -> Option<PathBuf>
fn output_path() -> Option<PathBuf>
Returns the output path to where T should be exported, relative to the output directory.
The returned path does not include any base directory.
When deriving TS, the output path can be altered using #[ts(export_to = "...")].
See the documentation of TS for more details.
If T cannot be exported (e.g because it’s a primitive type), this function will return
None.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.