0Pricing
TypeScript Academy · درس

عامل التأكيد على عدم كون القيمة null

استخدموا العامل ! لتأكيد أن القيمة ليست null أو undefined

عامل التأكيد على عدم كون القيمة null درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

معامل التأكيد بعدم كون القيمة فارغة

يخبر المعامل اللاحق ! TypeScript أن «هذه القيمة ليست null أو undefined هنا». وهو يزيل هاتين القيمتين من النوع من دون إجراء أي فحص وقت التشغيل.

function firstChar(s: string | null): string {
  return s!.charAt(0); // assert s is not null
}
console.log(firstChar('hello'));

موضع !

يوضع ! مباشرةً بعد التعبير الذي تؤكدونه، وقبل أي وصول لاحق إليه. وهو يزيل null | undefined من نوع ذلك التعبير.

type Box = { value?: number };
const box: Box = { value: 7 };
const n: number = box.value!; // value is number | undefined -> number
console.log(n);

تأكيد عدم الفراغ بعد حارس

أحيانًا تكونون قد ضمنتم منطقيًا وجود قيمة، لكن المصرّف لا يستطيع تتبع هذا الاستدلال. يتيح لكم ! المتابعة. ومع ذلك، يكون فحص وقت التشغيل الفعلي أوضح عادةً.

const list: Array<string | null> = ['a', null, 'c'];
const present = list.filter((x) => x !== null);
// TS may still see string | null; assert if certain:
console.log(present[0]!.toUpperCase());

يعمل في وقت الترجمة فقط، مجددًا

مثل as، يُحذف المعامل ! وقت التشغيل. فهو لا يُجري أي فحص. وإذا كانت القيمة فارغة فعلًا، فستحصلون على خطأ وقت التشغيل رغم اقتناع المصرّف بصحة الشيفرة.

function risky(s: string | null): number {
  return s!.length; // no runtime guard
}
console.log(risky('hi'));
// risky(null) would throw at runtime

خطر استخدام !

إذا أكدتم عدم فراغ قيمة يمكن أن تكون فارغة فعلًا، فقد أنشأتم خطأً خفيًا. إذ يتوقف المصرّف عن تحذيركم، ولا يظهر الخطأ إلا عندما تظهر تلك القيمة الفارغة فعلًا في بيئة الإنتاج.

type User = { name?: string };
const u: User = {};
// const len = u.name!.length; // compiles, crashes at runtime
console.log('name is undefined here -> ! would crash');

فضّلوا الفحص الفعلي

كلما كان ذلك عمليًا، استبدلوا ! بفحص فعلي للقيمة الفارغة أو بالتسلسل الاختياري. لا تكلف النسخة الآمنة سوى سطر واحد، وتزيل فئة كاملة من أعطال وقت التشغيل.

type User = { name?: string };
function nameLen(u: User): number {
  if (u.name) return u.name.length; // checked
  return 0;
}
console.log(nameLen({ name: 'Ada' }), nameLen({}));

تأكيد الإسناد المؤكد

هناك ميزة مرتبطة بذلك تُسمى تأكيد الإسناد المؤكد: let x!: T. وهي تَعِد المصرّف بأن x سيُسنَد إليه قبل استخدامه، رغم عدم تهيئته عند التصريح عنه.

let token!: string; // promise: assigned before use
function init() { token = 'abc123'; }
init();
console.log(token.length);

الإسناد المؤكد في الأصناف

يشيع ذلك في الأصناف التي تُعيَّن إحدى خصائصها بواسطة إطار عمل أو أسلوب تهيئة بدلًا من المُنشئ. ويؤدي وضع ! بعد اسم الخاصية إلى إسكات خطأ «لم يُسنَد إلى الخاصية بشكل مؤكد».

class Service {
  config!: { url: string }; // set later by setup()
  setup() { this.config = { url: '/api' }; }
}
const s = new Service();
s.setup();
console.log(s.config.url);

استخدموا الإسناد المؤكد بحذر

تأكيد الإسناد المؤكد وعد آخر لا يستطيع المصرّف التحقق منه. فإذا وصلتم إلى الخاصية قبل إسناد قيمة إليها، فستقرأون undefined وقت التشغيل من دون أي تحذير.

class Late {
  data!: number[];
  read() { return this.data.length; } // crashes if called before init
}
const l = new Late();
l.data = [1, 2];
console.log(l.read());

! في مقابل التسلسل الاختياري

لا تلجؤوا إلى ! عندما يكون ?. كافيًا. فالتسلسل الاختياري يتعامل مع القيم الفارغة بأمان وقت التشغيل، بينما لا يفعل ! سوى إسكات المصرّف. إنهما يحلان مشكلتين مختلفتين.

type Cfg = { db?: { host?: string } };
const c: Cfg = {};
console.log(c.db?.host ?? 'localhost'); // safe
// c.db!.host! would crash here

متى يكون ! مبررًا؟

يكون استخدام المعامل ! معقولًا عندما يكون لديكم ضمان حقيقي لا يستطيع المصرّف التعبير عنه، مثل قيمة أضفتموها للتو ثم قرأتموها مباشرةً. وحتى عندها، وثّقوا سبب أمان هذا الاستخدام.

const cache = new Map<string, number>();
cache.set('hits', 0);
// We just set it, so get is non-null:
const hits = cache.get('hits')!;
console.log(hits);

تحقق سريع

اختبروا مدى فهمكم لمعامل التأكيد بعدم كون القيمة فارغة.

مراجعة: التأكيد بعدم كون القيمة فارغة

لقد تعلمتم ما يلي:

  • تزيل اللاحقة ! النوعين null | undefined وقت الترجمة فقط.
  • لا تُجري أي فحص وقت التشغيل، ولذلك يظل التأكيد الخاطئ متسببًا في حدوث انهيار.
  • تُستخدم let x!: T كتأكيد التعيين المؤكد للقيم التي تتم تهيئتها لاحقًا.
  • فضّلوا الفحوصات الفعلية أو السلسلة الاختيارية، واحصروا استخدام ! في الضمانات الحقيقية.

بعد ذلك، سنتناول التأكيدات النوعية المزدوجة ومخاطرها.

const map = new Map<string, number>();
map.set('a', 1);
const v = map.get('a')!;
console.log(v);

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

هل درس «عامل التأكيد على عدم كون القيمة null» مجاني؟

نعم — نص درس «عامل التأكيد على عدم كون القيمة null» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «عامل التأكيد على عدم كون القيمة null»؟

استخدموا العامل ! لتأكيد أن القيمة ليست null أو undefined تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «عامل التأكيد على عدم كون القيمة null»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الكلمة المفتاحية as لتأكيد الأنواع
  2. عامل التأكيد على عدم كون القيمة null
  3. التأكيدات المزدوجة ومخاطرها
  4. التأكيدات مقابل حواجز الأنواع
← العودة إلى TypeScript Academy