"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > ما وراء نوع السلامة: تحليل محدد وقت تشغيل TypeScript

ما وراء نوع السلامة: تحليل محدد وقت تشغيل TypeScript

نشر في 2025-03-12
تصفح:134

Beyond Type Safety: making TypeScript smarter by Building a Runtime Picker

تنصل

مهلا ، قبل أن نبدأ ، اسمحوا لي أن أوضح شيئًا: بينما سأتحدث كثيرًا عن حزمةي ، أنا فقط أشارك تجربتي والرحلة التي قمت بها قبل بنائها. ( ولكن مرحبًا ، إذا كنت فضوليًا ، فإليك الرابط إلى الحزمة؟).


كيف قادني TypeScript إلى فكرة جديدة (وحزمة)

دعنا نرجع قليلاً. لذلك ، كنت أعمل مع TypeScript لفترة من الوقت الآن. لن أسمي نفسي شركة TypeScript Pro ، لكنني قمت ببناء عدد قليل من المشاريع الكبيرة وعملت معها في شركتي. كما تعلمون ، فإن بعض مشاريع "Hello World" المعتادة ، وبعض المشاريع الأكثر تعقيدًا قليلاً ، وبالطبع ، حصة عادلة من الرحلات إلى Google لمعرفة "ماذا يعني هذا الخطأ؟" أو "كيف يمكنني اختيار الحقول من واجهة مرة أخرى؟" (تحصل على هذه النقطة.؟)

في يوم من الأيام ، واجهت مشكلة أثناء العمل مع وظائف Firebase Cloud. كنت على نقطة النهاية

CreateUser ، وكتابة منطق التحقق من الصحة ، وتقليص البيانات ، والتعامل مع جنون طلب crud المعتاد. كان كل شيء يتحرك بسلاسة حتى ركضت إلى قطعة الكود هذه من مطور سابق:

firebase.collection ("المستخدمين"). إضافة (request.data.user) ؛
firebase.collection("users").add(request.data.user);
... وكان الخاص بي TypeScript Pro يصرخ. ؟

أعني ،

هيا ، كان هذا علامة حمراء ضخمة. يمين؟ كان إدراج بيانات المستخدم غير المسلحة مباشرة مثل هذا الأمر محفوفًا بالمخاطر - ماذا لو كانت بيانات الطلب تفتقد إلى بعض التحقق وانتهى بنا الأمر إلى إدراج الحقول غير المرغوب فيها في قاعدة البيانات؟ ليس رائعا.

لقد أزلت الرمز بسرعة ، لكن بعد ذلك ، تجمدت لثانية واحدة. ؟ حدق في شاشتي أفكر: "تمسك ، إذا قمت فقط بتعيين طلب. data إلى نوع واجهة المستخدم ، ألا يمنعني TypeScript من فعل شيء كهذا؟ ألا يصلح هذا المشكلة؟" (جديلة لمحة متفائلة على IDE ، في انتظار ظهور خطوط حمراء speciggly.)

لكن انتظر ...؟ ‍ typeScript هي

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

لذا ، استدعت أحد زملائي في الفريق وسألت ، "يا أخي ، إذا كان لدينا كائن يدعى الحروف الحرارية مع جميع الرسائل في الأبجدية ، وننشئ واجهة فقط twoletters التي تسمح فقط الرسائل" A "و" B "، ما يحدث عندما نلقي كائن الأبجدية على تلك الواجهة؟"


// كائن مع جميع الحروف الأبجدية أبجدية const = { ج: "التفاح" ، ب: "الموز" ، ج: "الكرز" ، D: "تاريخ" ، E: 'Estgplant' ، F: 'FIG' ، // ... على طول الطريق إلى z } ؛ // الواجهة التي تسمح فقط "A" و "B" الواجهة فقط twoletters { ج: سلسلة. ب: سلسلة. } // صب الحروف الهجائية فقط إلى twoletters const filledalphabets = الحروف الهجائية كـ oletters فقط ؛ console.log (filledalphabets) ؛

// Object with all alphabet letters
const alphabets = {
  a: 'Apple',
  b: 'Banana',
  c: 'Cherry',
  d: 'Date',
  e: 'Eggplant',
  f: 'Fig',
  // ... all the way to z
};

// Interface that only allows 'a' and 'b'
interface OnlyTwoLetters {
  a: string;
  b: string;
}

// Casting alphabets to OnlyTwoLetters
const filteredAlphabets = alphabets as OnlyTwoLetters;

console.log(filteredAlphabets);

اللعنة. كنت أعرف. كنت تحت تأثير الأمل -

على أمل

يمكن أن يمنعني TypeScript بطريقة سحرية من ارتكاب أخطاء في وقت التشغيل. ؟ ولكن بعد ذلك ، ضربني: ماذا لو كان بإمكان TypeScript فرض هذا في وقت التشغيل؟ ماذا لو تمكنا من إلقاء كائن إلى واجهة محددة ولدينا TypeScript

تجريد تلقائيًا

أي خصائص لم يتم تعريفها في الواجهة؟

أن

سيحل مشكلتي.


ولادة TS-Runtime-Picker

لذا ، مع لحظة Lightbulb هذه ، فكرت: "لماذا لا تجعل هذا حقيقة واقعة؟" إذا كان بإمكاني إلقاء request.data لواجهة المستخدم ، فقد يساعدني TypeScript في

تلقائيًا

إزالة أي خصائص إضافية ، مما يجعل الكائن آمنًا لإدراجه في Firebase. ؟ ومثل هذا ، ولدت فكرة

ts-runtime-picker

. كان الهدف بسيطًا: قم بإنشاء حزمة من شأنها أن تتيح لمستخدمي TpectScript تصفية الخصائص غير المرغوب فيها من كائن ، استنادًا إلى الحقول المحددة في واجهة محددة. ] أفضل جزء؟ سوف ينقذني من التحقق اليدوي وتصفية الحقول. لقد ولت أيام:


const filteredData = { الاسم: requestData.name ، العمر: requestData.age ، } ؛ firebase.collection ("المستخدمين"). إضافة (filteredData) ؛ // المزيد من العمل ، أقل متعة.

const filteredData = {
  name: requestData.name,
  age: requestData.age,
};

firebase.collection("users").add(filteredData);  // More work, less fun.

كيف يعمل: دع TypeScript يقوم بعمله

مع

ts-runtime-picker

، العملية بأكملها آلية. يمكنك إلقاء كائن إلى واجهة ، وستضمن الحزمة أن يتم الاحتفاظ فقط بالخصائص المحددة في الواجهة. إليك كيفية عمله في العمل:

قبل: التحقق اليدوي

مستخدم واجهة { الاسم: سلسلة. العمر: العدد ؛ } const requestData = {name: 'John' ، Age: 30 ، aggin: '123 Street'} ؛ // تحقق يدويًا وإزالة الحقول غير المرغوب فيها: const filteredData = { الاسم: requestData.name ، العمر: requestData.age ، } ؛ firebase.collection ('المستخدمين'). إضافة (filteredData) ؛ // ليست أنيقة جدا.

interface User {
  name: string;
  age: number;
}

const requestData = { name: 'John', age: 30, address: '123 Street' };

// Manually check and remove unwanted fields:
const filteredData = {
  name: requestData.name,
  age: requestData.age,
};

firebase.collection('users').add(filteredData);  // Not very elegant.
بعد: مع TS-Runtime-Picker

استيراد {pick} من 'ts-runtime-picker' ؛ مستخدم واجهة { الاسم: سلسلة. العمر: العدد ؛ } const requestData = {name: 'John' ، Age: 30 ، aggin: '123 Street'} ؛ // تقوم تلقائيًا بتصفية الخصائص غير الموجودة: const safedata = pick (requestData ، user) ؛ firebase.collection ('المستخدمين'). إضافة (safedata) ؛ // أنظف كثيرا!

import { pick } from 'ts-runtime-picker';

interface User {
  name: string;
  age: number;
}

const requestData = { name: 'John', age: 30, address: '123 Street' };

// Automatically filters out non-existent properties:
const safeData = pick(requestData, User);

firebase.collection('users').add(safeData);  // Much cleaner!
آمن

افتراضيًا. لا حاجة للشيكات اليدوية أو التلاعب بالكائن. يقوم TS-Runtime-Picker تلقائيًا بتعامله معها عن طريق تصفية جميع الحقول غير الموجودة في واجهة المستخدم. يمكنك فقط التركيز على منطقك الأساسي دون القلق بشأن إدخال المجال العرضي. ؟


قوة الكسل (وكيف يمكن أن تؤدي إلى الابتكار)

لذا ، قد تتساءل: "هل خرج هذا من الكسل الهائل؟" ولهذا ، أقول:

نعم ، ولكن أيضًا ، لا.

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

تجعل الأمور أسهل

قوة دافعة للابتكار. في الواقع ، على الرغم من "الكسل" الأولي ، قضيت

8 ساعات

بناء الحزمة. نعم ، هذا صحيح. ؟ ولكن هذا ما يسير في بعض الأحيان. "الحاجة إلى الولادة للاختراع" ، وهذه الحاجة إلى تجنب الشيكات المتكررة الشاقة أدت إلى حل جديد جعل حياتي في النهاية (ونأمل أن يكون الكثير من الآخرين للآخرين) أسهل كثيرًا.

هكذا ، بينما يمكنني

اللوم

كسل للحصول على الكرة ، كانت الحاجة إلى حل المشكلة التي أدت إلى ts-runtime-picker . وهذا هو الحال في بعض الأحيان ، أن تكون عالقًا أو كسولًا ليس بالضرورة شيئًا سيئًا - إنه مسقط رأس شيء جديد ومفيد!


خاتمة

وهذه هي القصة وراء الحزمة

ts-runtime-picker

رحلة من إحباط TypeScript إلى إنشاء أداة تحل مشكلة حقيقية. هذه الحزمة هي طريقتي في مساعدة المستخدمين على الاستفادة الكاملة من سلامة النوع - ليس فقط أثناء التطوير ولكن أيضًا في وقت التشغيل. إذا كنت قد سئمت من تصفية الحقول يدويًا أو تشعر بالقلق من التسلل إلى البيانات غير المرغوب فيها ، فاعط

ts-runtime-picker

لقطة. إنه شيء أقل ما يدعو للقلق ، ويجعل العمل مع TypeScript أكثر ذكاءً قليلاً. ؟

بيان الافراج يتم استنساخ هذه المقالة على: https://dev.to/hichemtab-tech/beyond-type-safety-making-typescript-smarter-by-building-a-runtime-picker-26d5؟1 إذا كان هناك أي انتهاك ، يرجى الاتصال [email protected] بحذفها.
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3