Menu
flag Ar iconالعربيةdown icon

الدوال في TypeScript: أنواع المعاملات والقيمة المُعادة وvoid

كيف تحدد أنواع الدوال في TypeScript: حدد نوع كل معامل، واكتب نوع القيمة المُعادة أو دعه يُستنتج، واستخدم void للدوال التي لا تعيد شيئًا، وحدد أنواع الدوال السهمية وتعبيرات الدوال والدوال غير المتزامنة ومعامل this.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

الدالة في TypeScript دالة JavaScript مع أنواع على معاملاتها، وعلى قيمتها المُعادة اختياريًا. يحصل كل معامل على تعليق نوع، ويأتي نوع القيمة المُعادة بعد قائمة المعاملات، ويفحص المترجم كل استدعاء مقابل الاثنين.

الاستدعاءان الخاطئان كلاهما خطأ وقت الترجمة (TS2345 وTS2554). تخبر تعليقات // @ts-expect-error المترجم بأن خطأ متوقع في السطر التالي، فيعمل بقية الملف. احذف أحدها وشغّل من جديد لترى الرسالة الحقيقية.

أنواع المعاملات

يُكتب كل معامل name: Type. تحت strict، المفعّل افتراضيًا في TypeScript 7، يكون المعامل الذي بلا تعليق نوع ولا سياق يُستنتج منه خطأ: Parameter 'x' implicitly has an 'any' type. (TS7006). لذلك عمليًا يُحدد نوع كل معامل في الدالة المستقلة.

أي نوع يصلح نوعًا لمعامل: الأنواع البدائية، والمصفوفات، وأنواع الكائنات، وunion، والدوال الأخرى.

تفحص TypeScript عدد الوسائط أيضًا. تمرير عدد أكثر أو أقل مما تعلنه الدالة خطأ، على خلاف JavaScript العادية التي تملأ الناقص بـ undefined وتتجاهل الزائد. لجعل معامل اختياريًا أو إعطائه قيمة افتراضية، انظر المعاملات الاختيارية.

أنواع القيم المُعادة: كتابتها أو استنتاجها

يأتي نوع القيمة المُعادة بعد القوس الختامي: function f(): Type. وهو اختياري. دونه تستنتج TypeScript النوع من كل return في الجسم.

يستحق التعليق مكانه عندما تكون الدالة مصدَّرة، أو عندما تكون لها عدة مسارات إعادة، أو عندما تكون تعاودية. عندها يظهر الخطأ داخل الدالة، عند return الخاطئة، بدل أن يظهر عند مستدعٍ. حالة نموذجية هي فرع ينسى الإعادة:

يبلّغ المترجم index.ts(2,32): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. أضف return "C"; أخيرة فيعمل. دون التعليق : string كانت الدالة ستُترجم بالنوع المستنتج "A" | "B" | undefined، وستنتقل المشكلة إلى من يستخدم الناتج.

void: الدوال التي لا تعيد شيئًا

الدالة التي تكتفي بفعل شيء (تسجيل أو كتابة أو تعديل) نوع قيمتها المُعادة void. وهو ما تستنتجه TypeScript عندما لا توجد return بقيمة، ويمكنك كتابته صراحة.

هذه القواعد المتعلقة بـ void تفاجئ الناس:

الحالةهل هي مسموحة؟
function f(): void { return 42; }لا: Type 'number' is not assignable to type 'void'. (TS2322)
const f: () => void = () => 42;نعم: تُعاد القيمة لكن يجب ألا يعتمد عليها المستدعون
function f(): undefined {}نعم (في TypeScript 5.1 وما بعده)
استخدام ناتج دالة void في ifلا: An expression of type 'void' cannot be tested for truthiness. (TS1345)

الصف الثاني مقصود. ولهذا يُترجم arr.forEach(x => list.push(x)) رغم أن push تعيد رقمًا. تعني void في نوع دالة «مهما أعادت، لا أحد يقرؤه». وللدالة التي لا تعود أبدًا (ترمي خطأ دائمًا أو تدور إلى الأبد)، يكون نوع القيمة المُعادة never.

الدوال السهمية وتعبيرات الدوال

تأخذ الدوال السهمية وتعبيرات الدوال التعليقات نفسها. يأتي نوع القيمة المُعادة بعد قائمة المعاملات، قبل =>.

دون الأقواس يكون (x, y) => { x, y } كتلة بلا return، فتعيد الدالة undefined. قواعد وقت التشغيل للدوال السهمية (لا this خاص بها، ولا arguments) هي نفسها في JavaScript؛ انظر الدوال السهمية في JavaScript.

عندما تُكتب دالة مضمّنة كوسيط، لا تحدد عادة أنواع معاملاتها إطلاقًا. تعرف TypeScript ما تستقبله الدالة الممررة من الدالة التي تُمرر إليها (الأنواع السياقية): في [1, 2].map(n => n * 2) يكون n من نوع number أصلًا. أما كتابة نوع دالة كقيمة، (n: number) => string، فمشروحة في أنواع الدوال.

إعادة عدة قيم

تعيد الدالة قيمة واحدة، فأعد كائنًا أو tuple وفككه.

نوع الـ tuple المُعاد يحتاج إلى التعليق. دونه يُستنتج [a, b] كـ string[]: يظل التفكيك يعمل، لكن النوع لم يعد يقول إن هناك عنصرين بالضبط.

الدوال غير المتزامنة

تعيد دالة async دائمًا Promise. اكتب نوع القيمة المُعادة كـ Promise<T>، حيث T ما تعيده الدالة في داخلها.

async function loadScore(id: number): Promise<number> {
  await new Promise((resolve) => setTimeout(resolve, 10));
  return id * 10;
}

async function main(): Promise<void> {
  const score = await loadScore(4); // score: number
  console.log("score", score);
}

main();

كتابة async function f(): number خطأ: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'? (TS1064).

معامل this

تحدد JavaScript قيمة this وقت الاستدعاء. وتتيح لك TypeScript إعلان ما يجب أن يكون عليه this بمعامل أول وهمي اسمه this. يُحذف من كود JavaScript المترجم ولا يمرره المستدعون.

interface Counter {
  count: number;
}

function increment(this: Counter, by: number): void {
  this.count += by;
}

const c = { count: 0, increment };
c.increment(2); // fine: this is c

increment(2);
// error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.

دون معامل this، يكون this داخل دالة مستقلة any ضمنيًا، ويبلّغ الوضع الصارم عن 'this' implicitly has type 'any' because it does not have a type annotation. (TS2683). في دوال الأصناف يكون نوع this هو نسخة الصنف أصلًا، لذلك يفيد المعامل غالبًا مع الدوال المستقلة المربوطة بكائنات ومع callbacks التي تستدعيها المكتبات بـ this محدد.

الأسئلة الشائعة

كيف أحدد نوع القيمة المُعادة للدالة في TypeScript؟

اكتب نقطتين ثم النوع بعد قائمة المعاملات: function total(a: number, b: number): number { ... }. وفي الدالة السهمية يوضع في المكان نفسه: const total = (a: number, b: number): number => a + b;. وإذا تركته تستنتج TypeScript نوع القيمة المُعادة من جمل return.

هل يجب أن أكتب نوع القيمة المُعادة دائمًا في TypeScript؟

إنه اختياري، لأن نوع القيمة المُعادة يُستنتج. اكتبه في الدوال المصدَّرة وفي الدوال ذات مسارات return المتعددة: يوثّق التعليق العقد، ويُبلَّغ عن return الخاطئة داخل الدالة بدل مستدعٍ بعيد.

ما الفرق بين void و undefined في TypeScript؟

void تعني «يجب ألا يستخدم المستدعي القيمة المُعادة». أما undefined فنوع قيمة ملموس. الدالة المعلنة (): void لا يجوز أن تعيد قيمة، لكن نوع الدالة الممررة () => void يقبل دالة تعيد شيئًا فعلًا، ويُتجاهل الناتج ببساطة. استخدم void للدوال التي لا تعيد شيئًا، وundefined فقط عندما يقارن المستدعون الناتج فعلًا بـ undefined.

كيف أعيد عدة قيم من دالة TypeScript؟

أعد كائنًا ({ min: number; max: number }) أو tuple ([number, number]) وفككه عند الاستدعاء. الكائنات أوضح عندما تكون للقيم معانٍ مختلفة؛ والـ tuples تُقرأ جيدًا للأزواج القصيرة مثل [value, setValue].

ما نوع القيمة المُعادة لدالة async في TypeScript؟

دائمًا Promise. دالة async تعيد number يكون نوع قيمتها المُعادة Promise<number>، وكتابة : number عليها خطأ ترجمة (TS1064). والدالة التي لا تعيد شيئًا نوعها Promise<void>.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن