ماژول - بهترین راه برای در معرض قرار دادن انواع برای مصرفکنندگان هنگام استفاده از تایپاسکریپت برای ایجاد کتابخانهها/بستهها چیست؟
من مدتی است که در حال جستجو و مطالعه اطلاعات مرتبط با این موضوع هستم، اما هنوز نمیتوانم آن را درک کنم.
وقتی من یک کتابخانه یا بسته با استفاده از تایپاسکریپت ایجاد میکنم، دوست دارم declaration را روی true تنظیم کنم تا وقتی کامپایلر ts کد منبع را کامپایل میکند، بهطور خودکار فایلهای اعلامیه را برای من تولید کند. یک کتابخانه یا بسته معمولی معمولاً یک فایل ورودی و تعدادی فایل وابسته به یکدیگر دارد. بنابراین خروجیهای نتیجه ساخت شبیه به این خواهند بود:
.
├── build
| ├── entry.js (or entry.min.js in production)
| ├── entry.d.ts (it depends on moduleA)
| ├── moduleA.d.ts (it depends on moduleB)
| ├── moduleB.d.ts
| ├── types.d.ts (contains shared types for every body)
| └── util.d.ts (declarations for some random util functions)
در package.json، من فقط این را تنظیم میکنم:
{
...
"main": "./build/entry.js",
"types": "./build/entry.d.ts",
...
}
مشکل این است که اگرچه entry.js همه API هایی را دارد که می خواهم در معرض دید مصرف کنندگان قرار دهم، entry.d.ts همه انواعی را که می خواهم در معرض نمایش قرار دهم ندارد. این به این دلیل است که حتی اگر entry.ts واردات از types.ts وارد شود، اعلانcهای نوع به طور خودکار از آن وارد نمیcشوند. ممکن است یک مصرف کننده بخواهد از تعدادی فهرستی استفاده کند که من در types.ts نگه داشته ام (و بنابراین types.d.ts)، که در entry.ts وجود ندارند (و بنابراین در entry.d.ts نیز وجود ندارند).
یک راه برای استفاده از نوعها این است که آنها را در فایل ورودی دوباره صادر کنید، چیزی شبیه به:
export * from './types';
// or
export { EnumA } from './types';
که به مصرفکننده اجازه میدهد این کار را انجام دهد:
import * as types from 'mylib';
// or
import { EnumA } from 'mylib';
این کاری است که در حال حاضر انجام میدهم، که بیشتر یک روند دستی است و احتمال زیادی وجود دارد که فراموش کنم بعضی از نوعها را صادر کنم که یک مصرفکننده واقعاً نیاز دارد تا از کتابخانه من استفاده کند. میتوانم تمام نوعها/رابطها/شمارههای شمارشی خود را در یک فایل واحد types.ts قرار دهم و همه چیز را صادر کنم، اما مطمئن نیستم که این کار درست باشد.
تیم تایپاسکریپت از نامفضاها برای مدیریت این موضوع استفاده میکند (برای مثال، انواع سرور و انواع سرویس)، اما به نظر من این اضافه است زیرا ما در حال حاضر از ماژولهای ES6 استفاده میکنیم. جزئیات بیشتر در این پست، مثال عالی فنجان برای توضیح نامفضاها با ماژولها.
راه حل دیگری برای این کار این است که اجازه دهید مصرفکننده انجام دهد
import * as types from 'mylib/build/types'
اما به نظر من این هم یک عمل بد است چون ما عملاً جزئیات پیادهسازی را در معرض دید مصرفکنندگان قرار میدهیم، که ممکن است در آینده آنها را تغییر دهیم.
من همچنین میخواهم به موارد بالا اضافه کنم که اگر بخواهم کتابخانهای برای کدهای ES5 با ساختار commonjs یا AMD تولید کنم، مستندات رسمی TypeScript میگوید از export = استفاده کنم. ظاهراً این باعث میشود دیگر نتوانید از export * from './types' استفاده کنید، بنابراین راهحلهای بالا دیگر کار نخواهند کرد.
در حال حاضر من در همان نقطه هستم. پیشنهادی دارید؟ فعلاً تمایل دارم از namespace استفاده کنم مثل کاری که تیمهای TypeScript انجام میدهند، اما دوست دارم نظرات بیشتری بشنوم.