لقد قمنا مؤخرًا بنقل 30000 سطر من شفرة JavaScript من نظام
MemSQL Studio الخاص بنا من Flow إلى TypeScript. في هذه المقالة سأشرح لماذا قمنا بتحويل قاعدة الكود وكيف حدث ذلك وما حدث.
إخلاء المسئولية: هدفي هو عدم انتقاد Flow على الإطلاق. أنا معجب بالمشروع وأعتقد أن هناك مساحة كافية في مجتمع جافا سكريبت لكلا خياري التحقق من النوع. في النهاية ، سيختار الجميع ما هو الأفضل له. آمل مخلصًا أن تساعد المقالة في هذا الاختيار.أولاً ، سوف أعرضك على الدورة. نحن في
MemSQL من المعجبين
بكتابات جافا سكريبت الثابتة والقوية لتجنب المشكلات الشائعة في الكتابة الديناميكية والضعيفة.
خطاب عن المشاكل الشائعة:
- اكتب الأخطاء في وقت التشغيل بسبب عدم مطابقة أجزاء مختلفة من الشفرة بأنواع ضمنية.
- يتم قضاء وقت طويل في كتابة اختبارات لأشياء تافهة مثل التحقق من معلمات الكتابة (يزيد وقت التشغيل أيضًا من حجم الحزمة).
- هناك نقص في تكامل المحرر / IDE ، لأنه بدون الكتابة الثابتة ، يكون من الصعب تنفيذ وظيفة الانتقال إلى التعريف وإعادة التجهيز الميكانيكي وغيرها من المهام.
- لا توجد طريقة لكتابة التعليمات البرمجية حول نماذج البيانات ، أي أنواع بيانات التصميم الأولى ، ثم الرمز "يكتب نفسه" بشكل أساسي.
هذه ليست سوى بعض فوائد الكتابة الثابتة ، كما تم إدراجها في
مقالة حديثة حول Flow .
في أوائل عام 2016 ، قمنا بتطبيق
tcomb لتطبيق نوع من الأمان في وقت تشغيل أحد مشاريع JavaScript الداخلية (إخلاء مسؤولية: لم أتعامل مع هذا المشروع). على الرغم من أن التدقيق في وقت التشغيل مفيد في بعض الأحيان ، إلا أنه لا يوفر جميع مزايا الكتابة الثابتة (قد يكون الجمع بين الكتابة الثابتة والتدقيق في وقت التشغيل مناسبًا لحالات معينة ، إلا أن الاختبارات البيئية تتيح لك القيام بذلك باستخدام tcomb و TypeScript ، على الرغم من أنني لم أجرب مطلقًا ) انطلاقًا من فهم هذا ، قررنا تنفيذ Flow لمشروع آخر بدأناه في عام 2016. في ذلك الوقت ، بدا Flow كخيار رائع:
- الدعم من Facebook ، الذي قام بعمل رائع في تطوير React وتنمية المجتمع (كما قاموا بتطوير React with Flow).
- تقريبا نفس النظام البيئي جافا سكريبت التنمية. كان أمرًا مخيفًا التخلي عن Babel لـ tsc (برنامج التحويل البرمجي لـ TypeScript) لأننا فقدنا المرونة في التبديل إلى اختبار نوع آخر (من الواضح أن الوضع قد تغير منذ ذلك الحين).
- لا حاجة إلى كتابة قاعدة الشفرة بأكملها (أردنا الحصول على فكرة عن جافا سكريبت المكتوب بشكل ثابت قبل الانتقال إلى الكل) ، ولكن فقط جزء من الملفات. يرجى ملاحظة أن كلاً من Flow و TypeScript يتيحان ذلك الآن.
- تفتقر TypeScript (في ذلك الوقت) إلى بعض الوظائف الأساسية المتاحة الآن ، فهذه أنواع البحث ، والمعلمات الافتراضية للأنواع العامة ، إلخ.
عندما بدأنا العمل على
MemSQL Studio في نهاية عام 2017 ، كنا نغطي أنواع التطبيق بالكامل (تمت كتابته بالكامل في JavaScript: يتم تنفيذ الواجهة الأمامية والخلفية في المتصفح). أخذنا Flow كأداة استخدمناها بنجاح في الماضي.
لكن لفت انتباهي إلى
بابل 7 بدعم من TypeScript . يعني هذا الإصدار أن التبديل إلى TypeScript لم يعد يتطلب انتقالًا إلى نظام TypeScript بالكامل ، ويمكنك الاستمرار في استخدام Babel لجافا سكريبت. الأهم من ذلك ، يمكننا
استخدام TypeScript فقط لفحص الكتابة ، وليس "لغة" كاملة.
شخصيا ، أعتقد أن فصل فحص الكتابة عن منشئ الشفرة هو طريقة أكثر أناقة للكتابة الثابتة (والقوية) في جافا سكريبت ، لأنه:
- نحن نشارك مشاكل الكود والكتابة. يؤدي ذلك إلى تقليل توقف فحص الكتابة وتسريع عملية التطوير: إذا كان التحقق من النوع بطيئًا لسبب ما ، فسوف يستمر إنشاء الشفرة بشكل صحيح (إذا كنت تستخدم tsc مع Babel ، فيمكنك تكوينه للقيام بالشيء نفسه).
- بابل لديه الإضافات والميزات الرائعة التي لا يملكها مولد TypeScript. على سبيل المثال ، يتيح لك Babel تحديد المتصفحات المدعومة وسيصدر لك رمزًا تلقائيًا. هذه وظيفة معقدة للغاية وليس من المنطقي دعمها في مشروعين مختلفين في نفس الوقت.
- أحب جافا سكريبت كلغة برمجة (باستثناء نقص الكتابة الثابتة) ، وليس لدي أي فكرة عن مدى وجود TypeScript ، بينما أؤمن بسنوات عديدة من ECMAScript. لذلك ، أفضل الكتابة و "التفكير" في جافا سكريبت (لاحظ أنني أقول "استخدم Flow" أو "استخدم TypeScript" بدلاً من "الكتابة في Flow" أو "TypeScript" ، لأنني دائمًا ما أمثلهم بالأدوات وليس لغات البرمجة).
بالطبع ، هذا النهج له بعض العيوب:
- يمكن لبرنامج التحويل البرمجي لـ TypeScript إجراء تحسينات قائمة على النوع نظريًا ، لكننا نفقد هذه الفرصة هنا.
- تكوين المشروع أكثر تعقيدًا مع زيادة في عدد الأدوات والاعتمادية. أعتقد أن هذه حجة ضعيفة نسبيًا: حفنة من بابل وفلو لم تخذلنا أبدًا.
TypeScript كبديل للتدفق
لقد لاحظت اهتمامًا متزايدًا بـ TypeScript في مجتمع JavaScript: عبر الإنترنت وبين المطورين من حوله. لذلك ، بمجرد أن اكتشفت أن Babel 7 يدعم TypeScript ، بدأت على الفور في دراسة خيارات الانتقال المحتملة. بالإضافة إلى ذلك ، واجهنا بعض عيوب Flow:
- ضعف جودة محرر / IDE التكامل (بالمقارنة مع TypeScript). Nuclide ، IDE الخاص بفيسبوك مع أفضل تكامل ، قديم بالفعل.
- مجتمع أصغر ، مما يعني عددًا أقل من تعريفات الأنواع للمكتبات المختلفة ، وهي ذات جودة أقل (يوجد حاليًا مستودع definitelyTyped به 19682 من نجوم GitHub ، ويحتوي المستودع المكتوب على التدفق على 3070 فقط).
- عدم وجود خطة تنمية عامة وسوء التفاعل بين فريق Flow على Facebook والمجتمع. يمكنك قراءة هذا التعليق من أحد موظفي Facebook لفهم الموقف.
- ارتفاع استهلاك الذاكرة وتسريبات متكررة - بالنسبة لبعض المطورين لدينا ، استغرق Flow في بعض الأحيان ما يقرب من 10 غيغابايت من ذاكرة الوصول العشوائي.
بالطبع ، يجب عليك دراسة كيف يناسبنا برنامج TypeScript. هذا سؤال معقد للغاية: تضمنت دراسة الموضوع قراءة مستفيضة للوثائق ، مما ساعد على فهم أنه لكل دالة Flow يوجد برنامج TypeScript مكافئ. بعد ذلك قمت باستكشاف خطة التطوير العام لـ TypeScript ، وأحببت حقًا الميزات التي تم التخطيط لها في المستقبل (على سبيل المثال ، الاشتقاق الجزئي لوسيطات الكتابة التي استخدمناها في Flow).
نقل أكثر من 30 ألف سطر من التعليمات البرمجية من Flow إلى TypeScript
بالنسبة للمبتدئين ، يجب ترقية بابل من 6 إلى 7. استغرقت هذه المهمة البسيطة 16 ساعة عمل ، لأننا قررنا ترقية Webpack 3 إلى 4. في الوقت نفسه ، وقد أدت بعض التبعيات القديمة في التعليمات البرمجية الخاصة بنا إلى تعقيد المهمة. الغالبية العظمى من مشاريع جافا سكريبت لن تواجه مثل هذه المشاكل.
بعد ذلك ، استبدلنا الإعداد المسبق لـ Babel Flow بالإعداد المسبق الجديد لـ TypeScript ، ثم أطلقنا لأول مرة برنامج التحويل البرمجي لـ TypeScript على جميع مصادرنا المكتوبة باستخدام Flow. والنتيجة هي
أخطاء في بناء جملة 8245 (لا يُظهر tsc CLI أخطاء حقيقية للمشروع حتى يتم إصلاح جميع أخطاء البنية).
في البداية ، أخافنا هذا الرقم (جدًا) ، ولكن سرعان ما أدركنا أن معظم الأخطاء كانت بسبب عدم دعم TypeScript لملفات .js. بعد أن درست الموضوع ، علمت أن ملفات TypeScript يجب أن تنتهي بـ .ts أو .tsx (إذا كانت تحتوي على JSX). هذا يبدو لي إزعاج واضح. لكي لا أفكر في وجود / غياب JSX ، أنا ببساطة أعيد تسمية جميع الملفات إلى .tsx.
تبقى حوالي 4000 أخطاء في بناء الجملة. يرتبط معظمها
باستيراد الكتابة ، والذي يمكن استبداله مع TypeScript ببساطة بالاستيراد ، وكذلك الفرق في تعيين الكائنات (
{||}
بدلاً من
{}
). طبقًا لعدد قليل من التعبيرات العادية ، تركنا 414 أخطاء في بناء الجملة. كان يجب إصلاح كل شيء آخر يدويًا:
- يجب استبدال النوع الوجودي ، الذي نستخدمه لاشتقاق وسائط من نوع عام جزئيًا ، بوسائل واضحة أو غير معروف لإخبار TypeScript بأن بعض الوسائط غير مهمة.
- اكتب $ Keys وأنواع التدفق المتقدمة الأخرى لها بناء جملة مختلف في TypeScript (على سبيل المثال ،
$Shape“”
يتوافق مع Partial“”
في TypeScript).
بعد تصحيح جميع أخطاء بناء الجملة ، أخبر tsc أخيرًا عدد أخطاء الكتابة الحقيقية في قاعدة الكود الخاصة بنا التي تبلغ حوالي 1300 فقط. الآن كان علينا الجلوس وقرر ما إذا كنت تريد المتابعة أم لا. بعد كل شيء ، إذا استغرقت الهجرة أسابيع ، فمن الأفضل أن تظل على تدفق. ومع ذلك ، قررنا أن ترقية الكود تتطلب أقل من أسبوع واحد من العمل من قبل مهندس واحد ، وهو أمر مقبول تمامًا.
يرجى ملاحظة أنه أثناء الهجرة اضطررت إلى إيقاف كل العمل في قاعدة الشفرة هذه. ومع ذلك ، في موازاة ذلك يمكنك بدء مشاريع جديدة - ولكن عليك أن تضع في اعتبارك مئات الأخطاء المحتملة في الكود الموجود ، وهذا ليس بالأمر السهل.
أي نوع من الأخطاء؟
TypeScript و Flow يعالجان كود JavaScript في عدة طرق. لذا ، فإن Flow أكثر صرامة فيما يتعلق ببعض الأشياء ، و TypeScript - بالنسبة إلى الآخرين. ستكون المقارنة العميقة بين النظامين طويلة جدًا ، ما عليك سوى إلقاء نظرة على بعض الأمثلة.
ملاحظة: تفترض جميع الروابط
المؤدية إلى رمل TypeScript المعلمات "الصارمة". لسوء الحظ ، عند مشاركة رابط ، لا يتم تخزين هذه الخيارات في عنوان URL. لذلك ، يجب تعيينها يدويًا بعد فتح أي رابط إلى صندوق الحماية من هذه المقالة.
invariant.js
تبين أن الوظيفة
invariant
شائعة جدًا في الكود المصدري الخاص بنا. فقط للاقتباس من الوثائق:
var invariant = require('invariant'); invariant(someTruthyVal, 'This will not throw');
الفكرة واضحة: وظيفة بسيطة ترمي خطأً في حالة ما. دعونا نرى كيفية
تنفيذها واستخدامها على تدفق:
type Maybe<T> = T | void; function invariant(condition: boolean, message: string) { if (!condition) { throw new Error(message); } } function f(x: Maybe<number>, c: number) { if (c > 0) { invariant(x !== undefined, "When c is positive, x should never be undefined"); (x + 1);
الآن قم
بتحميل نفس المقتطف في TypeScript . كما ترون من الرابط ، يعطي TypeScript خطأً ، لأنه لا يمكن أن يفهم أن
x
مضمون بعدم البقاء
undefined
بعد السطر الأخير. هذه في الواقع
مشكلة معروفة - لا يعرف TypeScript (الآن) كيفية القيام بهذا الاستنتاج من خلال دالة. ومع ذلك ، هذا قالب شائع جدًا في قاعدة الشفرة الخاصة بنا ، لذا اضطررت إلى استبدال كل مثيل ثابت يدويًا (أكثر من 150 قطعة) برمز آخر يعطي خطأً على الفور:
type Maybe<T> = T | void; function f(x: Maybe<number>, c: number) { if (c > 0) { if (x === undefined) { throw new Error("When c is positive, x should never be undefined"); } (x + 1);
لا تقارن حقًا
invariant
، ولكن ليس مثل هذه القضية الهامة.
$ ExpectError vs @ ts-ignore
يحتوي Flow على وظيفة مثيرة جدًا للاهتمام ، على غرار
@ts-ignore
، إلا أنه يلقي خطأً إذا كان السطر التالي
ليس خطأ. يعد هذا مفيدًا جدًا لكتابة "اختبارات الكتابة" التي تضمن أن التحقق من النوع (سواء كان TypeScript أو Flow) يعثر على أخطاء معينة في الكتابة.
لسوء الحظ ، لا تحتوي TypeScript على مثل هذه الوظيفة ، لذلك فقدت اختباراتنا بعض القيمة. وإنني أتطلع إلى
تنفيذ هذه الوظيفة على TypeScript .
أخطاء النوع العام ونوع الاستدلال
غالبًا ما يسمح TypeScript برمز أكثر وضوحًا من Flow ، كما في هذا المثال:
type Leaf = { host: string; port: number; type: "LEAF"; }; type Aggregator = { host: string; port: number; type: "AGGREGATOR"; } type MemsqlNode = Leaf | Aggregator; function f(leaves: Array<Leaf>, aggregators: Array<Aggregator>): Array<MemsqlNode> {
تدفق
infers leaves.concat (مجمعات) اكتب كـ Array <Leaf | مجمع> ، والذي يمكن بعد ذلك أن
Array<MemsqlNode>
على
Array<MemsqlNode>
. أعتقد أن هذا مثال جيد حيث يكون Flow أكثر ذكاءً ، ويحتاج TypeScript إلى القليل من المساعدة: في هذه الحالة ، يمكننا تطبيق تأكيد على النوع ، لكن هذا أمر خطير ويجب القيام به بعناية فائقة.
على الرغم من عدم وجود دليل رسمي ، أعتقد أن Flow أفضل بكثير من TypeScript في الاستدلال النوعي. آمل حقًا أن يصل TypeScript إلى مستوى التدفق ، حيث أن اللغة تتطور بشكل نشط للغاية ، وقد تم إجراء العديد من التحسينات الحديثة في هذا المجال. في العديد من الأماكن في الكود الخاص بنا ، كان على TypeScript المساعدة قليلاً من خلال التعليقات التوضيحية أو كتابة التأكيدات ، على الرغم من أننا
تجنبنا الأخيرة قدر الإمكان). دعنا نفكر في
مثال آخر (لدينا أكثر من 200 مثل هذه الأخطاء):
type Player = { name: string; age: number; position: "STRIKER" | "GOALKEEPER", }; type F = () => Promise<Array<Player>>; const f1: F = () => { return Promise.all([ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ]); };
لن يسمح لك TypeScript بكتابة هذا لأنه لن يسمح لك بالإعلان عن
{ name: "David Gomes", age: 23, type: "GOALKEEPER" }
ككائن من نوع
Player
(راجع صندوق الحماية لمعرفة الخطأ المحدد). هذه حالة أخرى حيث أجد TypeScript غير ذكي بما فيه الكفاية (على الأقل مقارنة بـ Flow ، والذي يفهم هذا الرمز).
هناك العديد من الخيارات لإصلاح هذا:
- قم بتعريف
"STRIKER"
لتكون "STRIKER"
بحيث يفهم TypeScript أن السلسلة عبارة عن تعداد صحيح للنوع "STRIKER" | "GOALKEEPER"
"STRIKER" | "GOALKEEPER"
. - قم بتعريف كل الكائنات كلاعب.
- أو ما أعتبره أفضل حل: ما عليك سوى مساعدة TypeScript دون استخدام أي عبارات كتابة بكتابة
Promise.all<Player>(...)
.
فيما يلي
مثال آخر (TypeScript) حيث يكون
Flow مرة أخرى أفضل في استنتاج الكتابة :
type Connection = { id: number }; declare function getConnection(): Connection; function resolveConnection() { return new Promise(resolve => { return resolve(getConnection()); }) } resolveConnection().then(conn => {
مثال صغير جدًا ولكنه مثير للاهتمام: يعتبر Flow أن
Array<T>.pop()
النوع
T
، ويعتبر TypeScript أنه
T | void
T | void
نقطة لصالح TypeScript ، لأنها تجبرك على التحقق من وجود عنصر (إذا كانت المصفوفة فارغة ،
Array.pop
undefined
). هناك العديد من الأمثلة الصغيرة مثل هذا حيث يكون TypeScript متفوقًا على Flow.
تعريفات TypeScript لتبعيات الجهات الخارجية
بالطبع ، عند كتابة أي تطبيق JavaScript ، سيكون لديك عدد قليل من التبعيات. يجب كتابتها ، وإلا فستفقد معظم إمكانيات تحليل النوع الثابت (كما هو موضح في بداية المقال).
يمكن أن تأتي المكتبات من npm مع تعريفات النوع Flow أو TypeScript ، مع أو بدون كليهما. في كثير من الأحيان لا يتم تزويد المكتبات (الصغيرة) بواحدة أو أخرى ، لذلك عليك أن تكتب تعريفات الأنواع الخاصة بك أو تستعيرها من المجتمع. يدعم كل من Flow و TypeScript مستودعات التعريف القياسية لحزم جافا سكريبت الخاصة بجهات خارجية: هذه
مكتوبة بتدفق و definitelyTyped.
يجب أن أقول أنه بالتأكيد أحببت الكثير. باستخدام التدفق المكتوب ، اضطررت إلى استخدام أداة CLI لتقديم تعريفات الأنواع لمختلف التبعيات في المشروع. يجمع DefinitelyTyped هذه الوظيفة مع أداة npm CLI عن طريق إرسال حزم
@types/package-name
إلى مستودع حزمة npm. هذا رائع جدًا ومبسَّط إلى حد كبير إدخال تعريفات الأنواع لتبعياتنا (المزاح ، التفاعل ، الإيواء ، رد الفعل المسترجع ، هذه مجرد أمثلة قليلة).
بالإضافة إلى ذلك ، قضيت وقتًا كبيرًا في ملء قاعدة بيانات definitelyTyped (لا تعتقد أن تعريفات النوع متكافئة عند نقل الرمز من Flow إلى TypeScript). لقد
أرسلت بالفعل بعض طلبات السحب ، ولم تكن هناك أي مشاكل في أي مكان. ما عليك سوى استنساخ المستودع وتعديل تعريفات النوع وإضافة الاختبارات - وإرسال طلب سحب. يصنف بوت GitHub definitelyTyped مؤلفي التعاريف التي قمت بتحريرها. إذا لم يقدم أي منهم ملاحظات في غضون 7 أيام ، فسيتم تقديم طلب السحب للنظر فيه إلى المشرف. بعد الدمج مع الفرع الرئيسي ، يتم إرسال إصدار جديد من حزمة التبعية إلى npm. على سبيل المثال ، عندما قمت بتحديث الحزمة @ types / redux-form لأول مرة ، تم إرسال الإصدار 7.4.14 تلقائيًا إلى npm. لذلك فقط قم بتحديث ملف package.json للحصول على تعريفات نوع جديدة. إذا لم تتمكن من انتظار اعتماد طلب السحب ، يمكنك دائمًا تغيير تعريفات الأنواع المستخدمة في مشروعك ، كما هو موضح
في إحدى المقالات السابقة .
بشكل عام ، تكون جودة تعريفات النوع في definitelyTyped أفضل بكثير بسبب مجتمع TypeScript الأكبر والأكثر ازدهارًا. في الواقع ، بعد نقل المشروع إلى TypeScript
، زادت تغطية الأنواع
من 88٪ إلى 96٪ ، ويرجع ذلك بشكل رئيسي إلى تعريفات أفضل لأنواع التبعية الخارجية ، مع وجود أنواع أقل.
الوبر والاختبارات
- لقد تحولنا من eslint إلى tslint (مع eslint لـ TypeScript ، بدا من الصعب البدء).
- اختبارات TypeScript تستخدم ts-jest . تتم كتابة بعض الاختبارات ، بينما لا يتم إجراء اختبارات أخرى (إذا تم كتابتها لفترة طويلة ، فإننا نحفظها كملفات .js).
ماذا حدث بعد إصلاح جميع أخطاء الكتابة؟
بعد 40 ساعة عمل ، وصلنا إلى آخر خطأ في الكتابة ، ونؤجله لفترة من الوقت باستخدام
@ts-ignore
.
بعد مراجعة تعليقات مراجعة التعليمات البرمجية وإصلاح بعض الأخطاء (لسوء الحظ ، اضطررت إلى تغيير رمز وقت التشغيل قليلاً لإصلاح المنطق الذي تعذر على TypeScript فهمه) ، تم إنهاء طلب السحب ، ومنذ ذلك الحين كنا نستخدم TypeScript. (ونعم ، لقد أصلحنا هذا
@ts-ignore
في طلب السحب التالي).
إلى جانب التكامل مع المحرر ، يشبه العمل مع TypeScript العمل مع Flow. أداء خادم التدفق أعلى قليلاً ، لكن هذه ليست مشكلة كبيرة ، لأنها تولد أخطاء للملف الحالي بسرعة متساوية. يتمثل الاختلاف الوحيد في الأداء في أن TypeScript يبلغ عن خطأ جديد بعد حفظ الملف بعد ذلك بقليل (بمقدار 0.5 إلى 1 ثانية). يكون وقت بدء تشغيل الخادم هو نفسه تقريبًا (حوالي دقيقتين) ، ولكنه ليس مهمًا جدًا. حتى الآن ، لم نواجه أي مشاكل مع استهلاك الذاكرة. يبدو أن tsc يستخدم باستمرار حوالي 600 ميجابايت.
قد يبدو أن دالة الاستدلال على الكتابة تمنح Flow ميزة كبيرة ، ولكن هناك سببان لعدم أهميتها:
- قمنا بتحويل قاعدة كود التدفق إلى TypeScript. من الواضح أننا صادفنا فقط تلك الشفرة التي يمكن لـ Flow التعبير عنها ، لكن لا يعمل TypeScript. إذا كان الترحيل قد حدث في الاتجاه المعاكس ، فأنا متأكد من أنه سيكون هناك أشياء يعرضها / يعرب عنها برنامج TypeScript بشكل أفضل.
- نوع الاستدلال مهم في المساعدة على كتابة رمز أكثر إيجازًا. ولكن على الرغم من ذلك ، فإن الأمور الأخرى أكثر أهمية ، مثل مجتمع قوي وتوافر تعريفات الأنواع ، لأنه يمكن إصلاح الاستدلال الضعيف للكتابة من خلال قضاء وقت أطول في الكتابة.
إحصائيات الرمز
$ npm run type-coverage
ما التالي؟
لم نقم بتحسين تحليل النوع الثابت. لدى MemSQL مشاريع أخرى ستتحول في النهاية من Flow إلى TypeScript (وبعض مشاريع JavaScript التي ستبدأ باستخدام TypeScript) ، ونريد أن نجعل تكوين TypeScript الخاص بنا أكثر صرامة. لدينا حاليًا خيار "
التحقق من
التقيد الصارم "
ممكّن ، ولكن لا يزال
noImplicitAny معطلاً. سنقوم أيضًا بإزالة
بضع عبارات خطرة من الكود.
يسعدني أن أشارككم كل ما تعلمته خلال مغامراتي بكتابة JavaScript. إذا كنت مهتمًا بموضوع معين ، فيرجى
إخبارنا بذلك .