Package: petit-ts
Petit tsA Library to easely convert your python types to typescript types.It's a part of thepetite_stack(not released yet, as not mature enough).Examplefrompetit_tsimportTSTypeStore,Namedstore=TSTypeStore()classJeb(Enum):A='R'# if you want an union to be named and not inlinedUserType=Named(Literal['admin','user'])TestUnion=Named(Union[str,int])classCreateUserDto(BaseModel):username:str# will be inlinedpassword:Union[str,Jeb]# won't be inlinedrole:UserType# won't be inlinedjeb:TestUnionstore.add_type(CreateUserDto)res=store.get_repr(CreateUserDto)print(res)# >>> "CreateUserDto"# Here you notice that we have the name instead of the body, so that you can use it# in another function easely# here we need to do this in order, to get all the required deps into our ts filenot_inlined=store.get_all_not_inlined()print(not_inlined)# >>> "type CreateUserDto  = {# 	username: string;# 	password: string | Jeb;# 	role: UserType;# 	jeb: TestUnion;# };# export enum Jeb {# 	A = "R",# };# type UserType = "admin" | "user";# type TestUnion = string | number /*int*/"not_inlined=store.get_all_not_inlined(exported_all=True)print(not_inlined)# >>> "export type CreateUserDto  = {# 	username: string;# 	password: string | Jeb;# 	role: UserType;# 	jeb: TestUnion;# };# export enum Jeb {# 	A = "R",# };# export type UserType = "admin" | "user";# export type TestUnion = string | number /*int*/"withopen('res.ts','w')asf:# write what you need to the filefinal=f'export a = function (a: any):{store.get_repr(CreateUserDto)};'final+=store.get_all_not_inlined()f.write(final)store=TSTypeStore(export_all=True)T=TypeVar('T')@dataclassclassjeb(Generic[T]):p:Timpl=Named(List[jeb[int]])store.get_full_repr(impl)# >> 'export type impl = (jeb<number /*int*/>)[];'# the jeb type is automatically added to the store and can be retrived with:# store.get_all_not_inlined()Supported types:NoneboolstrintfloatDict[K, V], Dict, dictList[T], List, list@dataclass, generic @dataclassOptional[T], Named(Optional[T])Union[A, B, ...], Named(Union[A, B, ...])Literal[values], Named(Literal[1, 2, '3']) with values = Union[int, str]Tuple[A, B, ...], Named(Tuple[A, B, ...])Add support for a custom typeExample for the BaseModel type:fromtypingimportTuple,Optional,Dict,Any,get_type_hintsfrompetit_tsimportClassHandler,TSTypeStorefrompydanticimportBaseModelstore=TSTypeStore()classBaseModelHandler(ClassHandler):@staticmethoddefis_mapping()->bool:returnTrue@staticmethoddefshould_handle(cls,store,origin,args)->bool:returnissubclass(cls,BaseModel)@staticmethoddefbuild(cls:BaseModel,store,origin,args)->Tuple[Optional[str],Dict[str,Any]]:name=cls.__name__fields=get_type_hints(cls)returnname,fieldsstore.add_class_handler(BaseModelHandler)You have to implement for theClassHandler:is_mappingshould_handlebuildIf this is a mapping, you should return the fields, aDict[str, Any]else you should return a stringFor the BasicHandler :buildshould_handleSupport for Named types:if you need a type to be exported with it's definition name, you can use theNamedfunction as such :P=Named(Union[str,int])# will be exported to type P = string | number;You can name any of :OptionalUnionLiteralTupleIf you have any problem, don't hesitate to open an issue on github !Support for type spoofing:As you'll see withpydantic.BaseModel, NamedUnion is not supported by default because of the way theUnionis defined in thetypinglib.In order to support this,petit_tsprovides thepatch_get_origin_for_Union, it will make other libraries
believeNamedUnionisUnion.
So you have to callpatch_get_origin_for_Union()before importing pydantic.Next steps :Handle multiple type of collectionHandle abstract typesChoose between interface and type