JSDoc 101 – انجمن DEV
من مدتی است که از JSDoc استفاده می کنم، و با تبلیغات تبلیغاتی اخیر به دلیل مهاجرت Svelte، امروز آمده ام تا نکات و نحوه استفاده از آنها را به اشتراک بگذارم.
اینها اصول اولیه چیزهایی هستند که شما نیاز خواهید داشت.
تایپ اسکریپت
نحو برای برخی چیزها متفاوت است، اما برای بیشتر موارد، فقط آن را به عنوان Typescript در نظر بگیرید و خوب خواهید بود.
فایل های .d.ts
من معمولاً از آنها برای انواع کمکی و کاربردی استفاده می کنم (ایجاد آنها راحت تر است، به خصوص آنهایی که دارای ژنریک هستند و شما می توانید فقط از آنها استفاده کنید)
برپایی
اضافه کردن // @ts-check
به بالای هر فایلی که نیاز دارید یا a اضافه کنید jsconfig,json
در ریشه پروژه خود با چک فایل های JS. (فعال کردن را فراموش نکنید js checking
در IDE شما).
JSDoc
@type
درست مانند TS، تفاوت بین:
/** @type {Foo} */
const foo = {}
const foo: Foo = {}
// and
const foo = /** @type {Foo} */ ({})
const foo = {} as Foo
// also includes
const foo = /** @satisfies {Foo} */ ({})
بسته به اینکه می خواهید TS چگونه نوع، تکمیل خودکار و خطاهایی را که به شما نشان می دهد مدیریت کند.
برای @type
من معمولاً با آن به صورت درون خطی می روم زیرا معمولاً از آن برای ارسال چیزی به نوع مورد نیاز خود استفاده می کنم:
// React common example
const [state, setState] = useState(/** @type {{ foo: Bar, bar: Baz }} */ ({}));
// ^? { foo: Bar, bar: Baz }
// And then sometimes you need some casting
Object.keys(state).map(k => k)
// ^? string
/** @type {(keyof state)[]} */ (Object.keys(state)).map(k => k)
// ^? "foo"|"bar"
و همانطور که می توانید ببینید هنگام ریختن چیزی به یک نوع، آن را بین پرانتز قرار می دهید /** @type {Foo} */ (toBeCast)
و البته در صورت نیاز می توانید /** @type {Foo} */(/** @type {unknown} */ (toBeCast))
و بله، برای این کار باید آن را داخل دو قرار دهید.
@typedef
احتمالاً برای انواع پیچیدهتر، از مقدار زیادی استفاده خواهید کرد.
برای این یکی، من آن را به عنوان یک بلوک و معمولاً به روش اول بدون هیچ نظری اعلام می کنم.
اما گاهی اوقات شما نسخه دوم را می خواهید زیرا هر کجا که این نوع ها بروند، نظرات را نیز انجام دهید.
/**
* @template {string} [T='bar']
* @typedef {{
* bar: T, // you can't see this comment
* baz?: string,
* }} Foo visible comments here
*/
/**
* @template {string} [T='bar']
* @typedef {Object} Foo2
* @property {T} bar this comment is visible
* @property {string} [baz] this is an optional property
*/
// both equivalent to:
type Foo<T extends string = "bar"> = {
bar: T;
baz?: string;
}
درباره @template
، ساده ترین راه برای اعلام یک ژنریک است @template T
.
یکی در مثال پیچیدهترین موردی است که با یک نوع گسترش و سپس یک مقدار پیشفرض به آن نیاز دارید، اما میتوانید فقط یکی یا دیگری را داشته باشید.