باید ها و نباید های تایپ اسکریپت [TypeScript]

باید ها و نباید های تایپ اسکریپت

این مقاله بخشی از سری آموزشی تایپ اسکریپت است. برای مشاهده بقیه بخش ها، فهرست مقالات را ببینید.

Number ، String ، Boolean ، Symbol و Object

هیچ وقت از نوع های Number ، String ، Boolean ، Symbol و یا Object استفاده نکنید. این نوع ها برای آبجکت های غیر-اولیه یا non-primitive هستند که در جاوا اسکریپت وجود دارند.

// !این کار را نکنید
function reverse(s: String): String;

از نوع های number ، string ، boolean ، symbol و object استفاده کنید:

// اوکی
function reverse(s: string): string;

جنریک ها

هیچ وقت در یک نوع جنریک، پارامتر نوعی که استفاده نشود، تعریف نکنید.

به مثال زیر توجه کنید:

interface Named<T> {
  name: string;
}
class MyNamed<T> implements Named<T> {
  name: 'mine';
}
function findByName<T>(x: Named<T>): T {
  // ...
}

var x: MyNamed<string>;
var y = findByName(x); // y: {} !رشته نیست

در مثال بالا انتظار داشتیم نوع خروجی تابع findByName رشته باشد (بخاطر MyNamed<string> ) ولی در واقع {} است چون پارامتر نوع T استفاده نشده است.

اگر مثال را به این صورت تغییر دهیم خروجی تابع چیزی که انتظار داشتیم می شود:

interface Named<T> {
  name: string;
  value: T; // <-- استفاده کردیم
}
class MyNamed<T> implements Named<T> {
  name: 'mine';
  value: T; // <-- استفاده کردیم
}
function findByName<T>(x: Named<T>): T {
  // ...
}

var x: MyNamed<string>;
var y = findByName(x); // y: string درست شد

any

سعی کنید هیچ وقت از any استفاده نکنید مگر اینکه در حال مهاجرت یک پروژه از جاوا اسکریپت به تایپ اسکریپت باشید. نوع any به کامپایلر می گوید بررسی نوع را کلا غیر فعال کند.

نوع any موقع مهاجرت و بازنویسی یک پروژه از جاوا اسکریپت به تایپ اسکریپت می تواند کمک کند تا به مرور زمان این بازنویسی انجام شود و فعلا کامپایلر به کد جاوا اسکریپت کاری نداشته باشد.

در مواقعی که نوع یک مقدار مشخص نیست، از unknown می توانید استفاده کنید.

نوع خروجی کال بک

برای خروجی کال بک هایی که مقدار خروجی نادیده گرفته خواهد شد از any استفاده نکنید:

// !این کار را نکنید
function fn(x: () => any) {
  x();
}

برای خروجی کال بک هایی که مقدار خروجی نادیده گرفته خواهد شد از void استفاده کنید:

// اوکی
function fn(x: () => void) {
  x();
}

چرا؟ چون استفاده از void امن تر است و اجازه اینکه به اشتباه مقدار خروجی استفاده شود را نمی دهد:

function fn(x: () => void) {
  const k = x();
  k.doSomething(); // تایپ اسکریپت اخطار می دهد
}

پارامتر های اختیاری در کال‌بک

برای نشان دادن اینکه یک پارامتر کال‌بک را کاربر می تواند استفاده نکند، آن را اختیاری نکنید:

// !این کار را نکنید
interface Fetcher {
  getObject(done: (data: unknown, elapsedTime?: number) => void): void;
}

نیازی به اختیاری کردن نیست، در جاوا اسکریپت همیشه می توانیم یک کال‌بک با پارامتر های کمتر را بجای یک کال‌بک با پارامتر های بیشتر استفاده کنیم. با اختیاری کردن فقط باعث می شویم کاربر (استفاده کننده) مجبور شود وجود آن پارامتر را همیشه چک کند.

پارامتر های کال بک ها را غیر-اختیاری بنویسید:

// اوکی
interface Fetcher {
  getObject(done: (data: unknown, elapsedTime: number) => void): void;
}

اورلود و کال بک

اورلود هایی که فقط تعداد پارامتر های کال بک هایشان فرق می کند ننویسید:

// !این کار را نکنید
// (فقط تعداد پارامتر های کال بک action فرق می کند)
declare function beforeAll(action: () => void, timeout?: number): void;
declare function beforeAll(
  action: (done: DoneFn) => void,
  timeout?: number
): void;

فقط یک اورلود با حداکثر تعداد پارامتر های کال بک بنویسید:

// اوکی
declare function beforeAll(
  action: (done: DoneFn) => void,
  timeout?: number
): void;

چرا؟ چون در جاوا اسکریپت همیشه می توانیم از یک کال بک با پارامتر های کمتر بجای کال بک اصلی استفاده کنیم.

ترتیب اورلود ها

اورلود های عمومی تر و کلی تر را قبل از اورلود های اختصاصی تر قرار ندهید:

// !این کار را نکنید
declare function fn(x: unknown): unknown;
declare function fn(x: HTMLElement): number;
declare function fn(x: HTMLDivElement): string;

var myElem: HTMLDivElement;
var x = fn(myElem); // x: unknown  :(

اورلود های اختصاصی تر را قبل از اورلود های کلی تر قرار دهید:

// اوکی
declare function fn(x: HTMLDivElement): string;
declare function fn(x: HTMLElement): number;
declare function fn(x: unknown): unknown;

var myElem: HTMLDivElement;
var x = fn(myElem); // x: string  :)

پارامتر های اختیاری بجای اورلود

اورلود هایی که می شود بجای آن از پارامتر های اختیاری استفاده کرد، تعریف نکنید:

// !این کار را نکنید
interface Example {
  diff(one: string): number;
  diff(one: string, two: string): number;
  diff(one: string, two: string, three: boolean): number;
}

هر جایی ممکن بود از پارامتر های اختیاری بجای اورلود استفاده کنید:

// اوکی
interface Example {
  diff(one: string, two?: string, three?: boolean): number;
}

نوع union به جای اورلود

اورلود هایی که می شود بجای آن از union استفاده کرد، تعریف نکنید:

// !این کار را نکنید
interface Moment {
  utcOffset(): number;
  utcOffset(b: number): Moment;
  utcOffset(b: string): Moment;
}

هر جایی ممکن بود از union بجای اورلود استفاده کنید:

// اوکی
interface Moment {
  utcOffset(): number;
  utcOffset(b: number | string): Moment;
}

قدم بعدی

در ادامه می توانید مقالات دیگر سری آموزشی تایپ اسکریپت را مطالعه کنید و آموزش های پروژه محور مرتبط با تایپ اسکریپت را بررسی کنید. برای یادگیری بهتر، علاوه بر مطالعه و تحقیق، سعی کنید تمرینات پروژه محور هم انجام دهید. برای تست سریع کد تایپ اسکریپت در مرورگر از TS Playground استفاده کنید.


کامنت ها