Trait typescript_type_def::TypeDef[][src]

pub trait TypeDef: 'static {
    const INFO: TypeInfo;
}
Expand description

A Rust type that has a corresponding TypeScript type definition.

For a Rust type T, the TypeDef trait defines a TypeScript type which describes JavaScript value that are equivalents of Rust values of type T as encoded to JSON using serde_json. The types are one-to-one, so decoding from TypeScript to JSON to Rust also works.

Implementing

Local Types

To derive this trait for your own types, use the #[derive(TypeDef)] macro.

Foreign Types

To use types from external crates in your own types, the recommended approach is to create a newtype wrapper and use the #[type_def(type_of = "T")] attribute to specify its type:

use serde::{Deserialize, Serialize};
use typescript_type_def::{write_definition_file, TypeDef};

// The Uuid type from the uuid crate does not implement TypeDef
// But we know that it serializes to just a string
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, TypeDef,
)]
#[serde(transparent)]
pub struct Uuid(#[type_def(type_of = "String")] pub uuid::Uuid);

// We can now use our newtype in place of the foreign type
#[derive(Debug, Serialize, Deserialize, TypeDef)]
pub struct User {
    pub id: Uuid,
    pub name: String,
}

let ts_module = {
    let mut buf = Vec::new();
    write_definition_file::<_, User>(&mut buf, Default::default()).unwrap();
    String::from_utf8(buf).unwrap()
};
assert_eq!(
    ts_module,
    r#"// AUTO-GENERATED by typescript-type-def

export default types;
export namespace types{
export type Uuid=string;
export type User={"id":types.Uuid;"name":string;};
}
"#
);

The other option if you don’t want to create a newtype is to use #[type_def(type_of = "T")] everywhere you use the type:

use serde::{Deserialize, Serialize};
use typescript_type_def::{write_definition_file, TypeDef};

#[derive(Debug, Serialize, Deserialize, TypeDef)]
pub struct User {
    #[type_def(type_of = "String")]
    pub id: uuid::Uuid,
    pub name: String,
}

let ts_module = {
    let mut buf = Vec::new();
    write_definition_file::<_, User>(&mut buf, Default::default()).unwrap();
    String::from_utf8(buf).unwrap()
};
assert_eq!(
    ts_module,
    r#"// AUTO-GENERATED by typescript-type-def

export default types;
export namespace types{
export type User={"id":string;"name":string;};
}
"#
);

std Types

TypeDef is implemented for std types as follows:

Rust typeTypeScript type
boolboolean
Stringstring
strstring
numeric typesnumber1
()null
(A, B, C)[A, B, C]
[T; N][T, T, ..., T] (an N-tuple)
Option<T>T | null
Vec<T>T[]
[T]T[]
HashSet<T>T[]
BTreeSet<T>T[]
HashMap<K, V>Record<K, V>
BTreeMap<K, V>Record<K, V>
&'static TT
Box<T>T
Cow<'static, T>T
PhantomData<T>T

  1. Numeric types are emitted as named aliases converted to PascalCase (e.g. Usize, I32, F64, NonZeroI8, etc.). Since they are simple aliases they do not enforce anything in TypeScript about the Rust types’ numeric bounds, but serve to document their intended range. 

Associated Constants

A constant value describing the structure of this type.

This type information is used to emit a TypeScript type definition.

Implementations on Foreign Types

Implementors