Skip to main content

A lightweight tool that helps you convert Python types to TypeScript types

Project description

GitHub Stars GitHub Forks GitHub Issues GitHub License

🐍➡️🚀 pytots

一个轻量级工具,帮助你将 Python 类型 优雅地转换为 TypeScript 类型


✨ 特性

  • 🔧 基础 Python → TypeScript 类型转换
  • 🌈 高级类型转换:联合类型、可选类型、字面量类型等
  • 🔄 循环引用处理:自动检测并化解类型循环依赖
  • 🎨 自定义类型映射:可扩展的映射表,随心定制
  • 🔌 插件系统:即插即用,轻松扩展新类型
  • 📄 多种输出格式:一键生成字符串或落盘文件

📦 支持的类型

类别 图标 类型示例
基础类型 🔤 str, int, float, bool, None, Any, object
容器类型 📚 List, Dict, Set, Tuple, Union, Optional
自定义类型 🧩 NewType, TypeVar, TypedDict
类类型 🏗️ dataclass 自动转换
函数类型 ⚙️ 函数签名级转换
插件加持 🔌 Pydantic BaseModel, SQLModel …

🚀 安装

包管理器 命令
uv uv add pytots
pip pip install pytots

🏁 快速开始

1️⃣ 基础使用

from pytots import convert_to_ts,get_output_ts_str
from typing import List,TypedDict

class TicketType(TypedDict):
    id: int
    name: str
    description: str
    
# 基础类型转换
o_type = convert_to_ts(TicketType)
print(o_type)  #输出 -> TicketType

# 获取完整的TypeScript代码字符串
ts_code = get_output_ts_str(None,True)
print(ts_code)

输出结果:

type TicketType = {
    id : number;
    name : string;
    description : string;
}

1.1 获取类型字符串

# 获取类型字符串
type_str = convert_to_ts(TicketType)
print(type_str)  # 输出: "TicketType"

1.2 输出到文件

# 直接输出到文件
output_ts_file("output/types.d.ts", "MyModule",True)

2️⃣ 自定义类型映射

目前支持以下类型自定义,默认的映射关系如下:

  • datetime.date => string
  • datetime.datetime => string
  • None => "undefined | null"

修改默认映射关系:

from pytots import replaceable_type_map
import datetime

# 自定义可替换类型映射
replaceable_type_map({
    datetime.date: "Date",
    datetime.datetime: "Date",
})

3️⃣ 插件系统

pytots提供了一个灵活的插件系统,允许你扩展对特定类型的支持。

3.1 内置插件

当前已内置了以下插件,无需注册自动启用:

  • DataclassPlugin:数据类插件,将Python dataclass转换为TypeScript类型。
  • TypedDictPlugin:字典插件,将Python TypedDict转换为TypeScript类型。

3.2 扩展插件

当前已集成了以下扩展插件:

  • PydanticPlugin:支持将Pydantic BaseModel转换为TypeScript类型。
  • SqlModelPlugin:支持将SQLModel转换为TypeScript类型。

扩展插件需要手动注册才能生效,使用方式:

from pytots import use_plugin
from pytots.plugin.plus import PydanticPlugin, SqlModelPlugin

# 注册插件
use_plugin(PydanticPlugin(), SqlModelPlugin())

3.3 修改插件默认行为:

系统默认在处理dataclass和typedict时,会使用type前缀的TypeScript类型。如果需要将其修改为interface,可以通过覆盖插件默认行为实现。

from pytots import override_plugin
from pytots.plugin.inner import DataclassPlugin, TypedDictPlugin

# 覆盖默认插件行为
override_plugin(
    DataclassPlugin(dict(type_prefix="interface")),
    TypedDictPlugin(dict(type_prefix="interface"))
    )

3.4 自定义插件

根据需要自定义插件,继承DataclassPlugin插件类,并实现is_supported方法。

3.4.1 插件简单用法示例

假设你有一些类,你想将其转换为TypeScript类型。

from typing import Generic,TypeVar

T = TypeVar("T")

class MyUser:
    id: int
    name: str

class MyAdmin(MyUser):
    role: str

class MyTicket(Generic[T]):
    id: int
    name: str
    description: str|None
    exc: T|None


class MyTicketAdmin(MyTicket[MyAdmin]):
    pass
    

自定义插件

from pytots import Plugin
from typing import Any

class MyCustomPlugin(DataclassPlugin):
    name = "MyCustomPlugin"    # 插件名称
    type_prefix = "interface"  # 使用interface前缀

    def is_supported(self, python_type) -> bool:
        return python_type in [MyUser,MyTicket,MyAdmin,MyTicketAdmin]

使用自定义插件

from pytots import use_plugin
from pytots import convert_to_ts,get_output_ts_str

use_plugin(MyCustomPlugin())

# 转换自定义类型
o_type = convert_to_ts(MyTicketAdmin)
print(o_type)  #输出 -> MyTicketAdmin

# 查看转换后的具体ts代码
ts_code = get_output_ts_str(None,True)
print(ts_code)

转换结果:

interface MyAdmin {
    id : number;
    name : string;
    role : string;
}
interface MyTicket<T extends any> {
    id : number;
    name : string;
    description ? : string | null | undefined;
    exc ? : T | null | undefined;
}
interface MyTicketAdmin extends MyTicket<MyAdmin> {
    id : number;
    name : string;
    description ? : string | null | undefined;
    exc ? : MyAdmin | null | undefined;
}
3.4.2 插件高级用法示例

实现对特定类型的转换或过滤一些类型时。可继承Plugin类,实现converteris_supported方法。如有大量现有类需要直接进行字符串映射时,可以定义TYPES_MAP字典,键为Python类型,值为对应的TypeScript类型的字符串。

以下示例演示过滤掉id字段:

from pytots.plugin.tools import generic_feild_fill,assemble_interface_type

class MyCustomPlugin(Plugin):
    
    name = "MyCustomPlugin"
    type_prefix = "interface"
    
    def is_supported(self, python_type) -> bool:
        return python_type in [MyUser,MyTicket,MyAdmin,MyTicketAdmin]

    def converter(self, python_type, **extra) -> str:
        class_name = python_type.__name__
        fields = []
        for field, field_type in get_type_hints(python_type).items():
            ts_type = generic_feild_fill(self,field_type)

            # 过滤掉id字段
            if field == "id":
                continue
            
            # 处理可选字段
            if "undefined" in ts_type:
                fields.append(f"{field}?: {ts_type};")
            else:
                fields.append(f"{field}: {ts_type};")

        fields_str = "\n  ".join(fields)
        
        return assemble_interface_type(self, class_name, fields_str)

同上面一样执行,得到转换结果:

interface MyAdmin {
    name : string;
    role : string;
}
interface MyTicket<T extends any> {
    name : string;
    description ? : string | null | undefined;
    exc ? : T | null | undefined;
}
interface MyTicketAdmin extends MyTicket<MyAdmin> {
    name : string;
    description ? : string | null | undefined;
    exc ? : MyAdmin | null | undefined;
}

🔌 核心接口

函数 说明 签名
convert_to_ts 将单个 Python 类型转为 TypeScript 类型字符串 convert_to_ts(python_type) -> str
get_output_ts_str 获取当前已转换的全部 TypeScript 代码 get_output_ts_str(module_name=None, format=False) -> str
output_ts_file 将结果直接写入 .d.ts 文件 output_ts_file(file_path, module_name=None, format=False) -> None
replaceable_type_map 全局覆盖默认类型映射表 replaceable_type_map(type_map: dict[type, str]) -> None
use_plugin 注册一个或多个插件 use_plugin(*plugins: Plugin) -> None
override_plugin 用新实例覆盖同名插件 override_plugin(*plugins: Plugin) -> None

重要特性:

自动级联:只要调用一次 convert_to_ts,其依赖的所有类型会被隐式转换并缓存,后续直接通过 get_output_ts_str 即可一次性拿到完整代码。

你可能发现了前面的示例我们并没有每一个类型都去处理,但是却转换了全部相关的类型。 这是因为pytots在处理类型时,会自动地处理所有相关的类型。

convert_to_ts

将Python类型转换为TypeScript类型。

convert_to_ts(python_type) -> str

get_output_ts_str

获取转换后的TypeScript代码字符串。

get_output_ts_str(module_name: str | None = "PytsDemo", format: bool = False) -> str

output_ts_file

将转换结果输出到文件。

output_ts_file(file_path: str, module_name: str | None = "PytsDemo", format: bool = False) -> None

replaceable_type_map

自定义可替换类型映射。

replaceable_type_map(type_map: dict[type, str]) -> None

use_plugin

注册插件。

use_plugin(*plugins: Plugin) -> None

override_plugin

覆盖已注册的插件。

override_plugin(*plugins: Plugin) -> None

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytots-0.3.5.tar.gz (34.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytots-0.3.5-py3-none-any.whl (37.6 kB view details)

Uploaded Python 3

File details

Details for the file pytots-0.3.5.tar.gz.

File metadata

  • Download URL: pytots-0.3.5.tar.gz
  • Upload date:
  • Size: 34.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.8

File hashes

Hashes for pytots-0.3.5.tar.gz
Algorithm Hash digest
SHA256 a4efcc84a2749c5660b3ce727f38527303ceea493a7401f42127501c62fd4979
MD5 4c00af3a7f59a0744d4a8ba3005a7c22
BLAKE2b-256 a30908763dd08f5e379546355123ec86c2cee78fcd921fa00801fb1f5fb0f567

See more details on using hashes here.

File details

Details for the file pytots-0.3.5-py3-none-any.whl.

File metadata

  • Download URL: pytots-0.3.5-py3-none-any.whl
  • Upload date:
  • Size: 37.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.8

File hashes

Hashes for pytots-0.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 08c323e4e9917a488dce60c0aef8ae6ada9def735dcc862c269dac2405f70d58
MD5 707b97d44f74f177f654fa8169b76258
BLAKE2b-256 6b144dc12f3fe84ffa30582f1abca9bd90d3bf07d3babe898c1888fa452996f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page