كتاب “Professional TypeScript. تطوير تطبيقات JavaScript قابلة للتطوير "

صورةسيشهد أي مبرمج يعمل بلغة مكتوبة ديناميكيًا أن مهمة تحجيم الشفرة صعبة للغاية وتتطلب فريقًا كبيرًا من المهندسين. هذا هو السبب في أن Facebook و Google و Microsoft قد توصلوا إلى كتابة ثابتة للكود المكتوب ديناميكيًا.



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



TypeScript ، على عكس العديد من اللغات المكتوبة الأخرى ، هو موجه للتطبيق. يقدم مفاهيم جديدة تسمح لك بالتعبير عن الأفكار بمزيد من الإيجاز والدقة ، وبناء تطبيقات حديثة قابلة للتطوير وآمنة بسهولة.



يساعد Boris Cherny على فهم جميع الفروق الدقيقة وقدرات TypeScript ، ويعلمك التخلص من الأخطاء وتوسيع نطاق الشفرة.



هيكل الكتاب



لقد حاولت (المؤلف) أن أقدم لك فهمًا نظريًا لكيفية عمل TypeScript وكمًا لا بأس به من النصائح العملية حول كيفية كتابة التعليمات البرمجية.



تعد TypeScript لغة عملية ، لذا فإن النظرية والتطبيق يكملان بعضهما البعض في الغالب في الكتاب ، ولكن الفصلين الأولين يغطيان النظرية بشكل أساسي ، وفي النهاية يتم تقديم الممارسة فقط.



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



تنتهي معظم الفصول بمجموعة من التمارين. حاول أن تفعلها بنفسك من أجل استيعاب المادة بشكل أفضل. الإجابات عليها متوفرة هنا .



ترحيل مرحلي من JavaScript إلى TypeScript



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



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



  • إضافة TSC إلى المشروع.
  • ابدأ في التحقق من أنواع كود JavaScript الموجودة.
  • انقل كود JavaScript إلى TypeScript ملفًا بملف.
  • تثبيت نوع الإقرارات للتبعيات. أي ، قم بتخصيص الأنواع للتبعيات التي لا تحتوي عليها ، أو اكتب إقرارات النوع للتبعيات غير المصنفة وأرسلها مرة أخرى إلى DefinitelyTyped1.
  • تفعيل الوضع المتشدد لقاعدة التعليمات البرمجية.


قد تستغرق هذه العملية بعض الوقت ، ولكنك سترى على الفور مكاسب الأمان والأداء ومزايا أخرى لاحقًا. دعنا نلقي نظرة على الخطوات المذكورة.



الخطوة 1: إضافة TSC



عند العمل باستخدام قاعدة تعليمات برمجية تجمع بين TypeScript و JavaScript ، دع TSC أولاً يجمع ملفات JavaScript مع ملفات TypeScript في إعدادات tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true
}


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



مع ضبط allowJs على صحيح ، لن يتحقق TypeScript من الأنواع الموجودة في كود JavaScript الحالي ، ولكنه سيحول هذا الرمز إلى ES3 أو ES5 أو الإصدار الذي تم تعيينه كهدف في ملف tsconfig.json باستخدام نظام الوحدة النمطية الذي طلبته (في حقل الوحدة النمطية json). تم الانتهاء من الخطوة الأولى. قم بإلزامها وربت على ظهرها - تستخدم قاعدة التعليمات البرمجية الآن TypeScript.



الخطوة 2 أ: تمكين التحقق من نوع JavaScript (اختياري)



الآن وقد قام TSC بمعالجة JavaScript ، فلماذا لا تتحقق من أنواعه؟ حتى إذا لم تكن هناك تعليقات توضيحية لنوع صريح ، تذكر أن TypeScript يمكنه الاستدلال على أنواع تعليمات JavaScript البرمجية بنفس طريقة كتابة TypeScript البرمجية. قم بتضمين الخيار المطلوب في tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true,
     "checkJs": true
}


الآن ، عندما يقوم TypeScript بتجميع ملف JavaScript ، فإنه سيحاول استنتاج الأنواع والتحقق منها تمامًا كما يفعل مع تعليمات TypeScript البرمجية.



إذا كانت قاعدة التعليمات البرمجية الخاصة بك كبيرة وعندما تقوم بتمكين checkJs فإنها تواجه الكثير من الأخطاء في وقت واحد ، قم بإيقاف تشغيلها. بدلاً من ذلك ، قم بتمكين فحص ملف JavaScript واحدًا تلو الآخر عن طريق إضافة // @ ts-check التوجيه (تعليق عادي في أعلى الملف). أو ، إذا أدت الملفات الكبيرة إلى ظهور مجموعة من الأخطاء التي لا تريد إصلاحها بعد ، فاترك checkJs ممكّنًا وأضف التوجيه // @ ts-nocheck لهذه الملفات.



لا يمكن لـ TypeScript أن يستنتج أنواعًا لكل شيء (على سبيل المثال ، لا يستنتج أنواع معلمات الوظيفة) ، لذلك سوف يستنتج العديد من الأنواع في JavaScript مثل أي منها. إذا تم تمكين الوضع المتشدد في tsconfig.json (موصى به) ، فقد تفضل السماح بأي وضع ضمني أثناء الترحيل. أضف ما يلي إلى tsconfig.json:



{
     "compilerOptions": {
     "allowJs": true,
     "checkJs": true,
     "noImplicitAny": false
}


تذكر تشغيل noImplicitAny مرة أخرى عند الانتهاء من ترحيل الجزء الأكبر من التعليمات البرمجية الخاصة بك إلى TypeScript. سيجد هذا على الأرجح العديد من الأخطاء الفائتة (ما لم تكن Zenidar ، تلميذ ساحرة JavaScript Bavmorda ، والذي يمكنه التحقق من قوة عين عقله بجرعة من الشيح).


عندما ينفذ TypeScript كود JavaScript ، فإنه يستخدم خوارزمية استدلال أكثر ليونة من كود TypeScript. يسمى:



  • جميع معلمات الوظيفة اختيارية.
  • يتم الاستدلال على أنواع خصائص الوظائف والفئات بناءً على استخدامها (بدلاً من الاضطرار إلى الإعلان عنها مسبقًا):



    class A {
        x = 0 // number | string | string[],    .
         method() {
                 this.x = 'foo'
         }
         otherMethod() {
                 this.x = ['array', 'of', 'strings']
         }
    
    }
  • بعد التصريح عن كائن أو فئة أو وظيفة ، يمكنك تعيين خصائص إضافية لها. خلف الكواليس ، يقوم TypeScript بذلك عن طريق إنشاء مساحة اسم مناسبة لكل إعلان عن الوظيفة وإضافة توقيع فهرس تلقائيًا إلى كل كائن حرفي.


الخطوة 2 ب: إضافة تعليقات JSDoc (اختياري)



قد تكون في عجلة من أمرك وتحتاج فقط إلى إضافة تعليق توضيحي من نوع واحد لوظيفة جديدة تمت إضافتها إلى ملف JavaScript قديم. يمكنك استخدام التعليق التوضيحي لـ JSDoc للقيام بذلك حتى تتمكن من تحويل هذا الملف إلى TypeScript.



ربما تكون قد رأيت JSDoc من قبل. هذه تعليقات مثل هذه في الجزء العلوي من الكود مع تعليقات توضيحية تبدأ بـ @ ، مثلباراموreturns وما إلى ذلك. يفهم TypeScript JSDoc ويستخدمه كمدخل لمدقق النوع مع التعليقات التوضيحية للنوع الصريح.



افترض أن لديك ملف خدمة 3000 خط (نعم ، أعرف أن "صديقك" كتبه). تقوم بإضافة وظيفة خدمة جديدة إليها:



export function toPascalCase(word) {
       return word.replace(
             /\w+/g,
             ([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
       )
}


بدون تحويل كامل لـ utils.js إلى TypeScript ، والذي سيكشف بالتأكيد عن مجموعة من الأخطاء ، يمكنك فقط إضافة تعليق توضيحي لوظيفة toPascaleCase ، مما يؤدي إلى إنشاء جزيرة أمان صغيرة في بحر JavaScript غير مكتوب:



/**
     * @param word {string}    .
     * @returns {string}   PascalCase
     */
export function toPascalCase(word) {
     return word.replace(
           /\w+/g,
           ([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
     )
}


بدون هذا التعليق التوضيحي ، يمكن لـ JSDoc TypeScript الاستدلال على نوع toPascaleCase كـ (word: any) => string. الآن ، عند التحويل البرمجي ، ستعرف أن نوع toPascaleCase هو (word: string) => string. وتحصل على وثائق مفيدة.



لمزيد من المعلومات حول التعليقات التوضيحية لـ JSDoc ، تفضل بزيارة TypeScript Wiki (https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript).



الخطوة 3: إعادة تسمية الملفات إلى ts



بمجرد إضافة TSC إلى عملية الإنشاء الخاصة بك والبدء في التحقق اختياريًا من الأنواع والتعليق على كود JavaScript حيثما أمكن ، حان الوقت للتبديل إلى TypeScript.



ملف حسب الملف ، قم بتحديث أذونات الملف من .js (أو .coffee ، es6 ، إلخ) إلى .ts. مباشرة بعد إعادة تسمية الملفات في المحرر ، سترى أصدقاء متموجين باللون الأحمر يظهرون يشيرون إلى أخطاء الكتابة ، والحالات المفقودة ، والشيكات الفارغة المنسية ، والأخطاء المطبعية في أسماء المتغيرات. هناك طريقتان لإزالتها.



  1. . , , , . checkJs, noImplicitAny tsconfig.json, any , , JavaScript .
  2. .ts tsconfig.json ( strict false), . any, . . , strict (noImplicitAny, noImplicitThis, strictNullChecks . .), . ( .)


, TODO any any, . , :



// globals.ts
type TODO_FROM_JS_TO_TS_MIGRATION = any

// MyMigratedUtil.ts
export function mergeWidgets(
       widget1: TODO_FROM_JS_TO_TS_MIGRATION,
       widget2: TODO_FROM_JS_TO_TS_MIGRATION
): number {
       // ...
}


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



الخطوة 4: تفعيل الدقة



بمجرد نقل كتلة حرجة من تعليمات JavaScript البرمجية ، سترغب في جعلها آمنة بالكامل باستخدام علامات TSC الأكثر صرامة واحدة تلو الأخرى (انظر الملحق E للحصول على قائمة كاملة من العلامات).



عند الانتهاء ، يمكنك إيقاف تشغيل علامات TSC المسؤولة عن التفاعل مع JavaScript ، مع التأكيد على أن كل التعليمات البرمجية الخاصة بك مكتوبة بلغة TypeScript المكتوبة بقوة:



{
     "compilerOptions": {
     "allowJs": false,
     "checkJs": false
}


سيؤدي ذلك إلى كشف أي أخطاء متبقية في النوع. قم بإصلاحها واحصل على قاعدة أكواد آمنة خالية من العيوب والتي قد يربكها معظم مهندسي OCaml القاسيين من أجلها.

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



البحث عن أنواع JavaScript



عندما تقوم باستيراد ملف JavaScript من ملف TypeScript ، يبحث TypeScript عن تعريفات النوع له باستخدام الخوارزمية التالية (تذكر ، في TypeScript ، يتم استخدام "file" و "module" بالتبادل):



  1. .d.ts , .js. .js.

    , :



    my-app/

    ├──src/

    │ ├──index.ts

    │ └──legacy/

    │ ├──old-file.js

    │ └──old-file.d.ts



    old-file ( ) index.ts:



    // index.ts

    import './legacy/old-file'



    TypeScript src/legacy/old-file.d.ts ./legacy/old-file.
  2. , allowJs checkJs true, .js ( JSDoc) any.




TSC-: TYPEROOTS ( )



TypeScript node modules/@types , (../node modules/@types . .). .



, typeRoots tsconfig.json , . , TypeScript typings node modules/@types:



{
     "compilerOptions": {
            "typeRoots" : ["./typings", "./node modules/@types"]
     }
}


types tsconfig.json, , TypeScript . , , React:



{
     "compilerOptions": {
             "types" : ["react"]
     }
}




عند استيراد وحدة JavaScript لجهة خارجية (حزمة NPM التي قمت بتثبيتها في وحدات العقدة) ، يستخدم TypeScript خوارزمية مختلفة قليلاً:



  1. يبحث عن تعريف النوع المحلي للوحدة ، وإذا وجد ، يستخدمه.



    على سبيل المثال ، تبدو بنية الدليل الخاص بك كما يلي:



    my-app /

    ├──node_modules /

    │ └──foo /

    ├──src /

    │ ├──index.ts

    │ └──types.d.ts



    هذه هي الطريقة التي يبدو بها type.d .ts:



    // types.d.ts
    declare module 'foo' {
          let bar: {}
          export default bar
    }


    إذا قمت بعد ذلك باستيراد foo ، فسيستخدم TypeScript إعلان الوحدة الخارجية في type.d.ts كنوع مصدر له:



    // index.ts

    import bar from 'foo'
  2. package.json, . types typings, .d.ts, , .
  3. أو سوف يتنقل خلال الدلائل بحثًا عن دليل وحدات العقدة / @ type ، والذي يحتوي على تعريفات النوع للوحدة النمطية.



    على سبيل المثال ، قمت بتثبيت



    React : npm install reaction - save

    npm install @ types / reaction - save-dev



    my-app /

    ├──node_modules /

    │ ├── @ types /

    │ │ └──react /

    │ └── رد فعل /

    ├──src /

    │ └──index.ts



    عند استيراد React ، سيجد TypeScript دليل @ type / رد فعل ويستخدمه كمصدر لإعلانات النوع له:



    // index.ts

    import * as React from 'رد فعل'
  4. خلاف ذلك ، سيتم الانتقال إلى الخطوات 1-3 من خوارزمية البحث من النوع المحلي.


لقد قمت بإدراج عدد قليل من الخطوات ، لكنك ستعتاد عليها.



نبذة عن الكاتب



بوريس تشيرني هو كبير المهندسين وقائد المنتج في Facebook. عمل سابقًا في VC و AdTech ومجموعة متنوعة من الشركات الناشئة ، ومعظمها غير موجود اليوم. إنه مهتم بلغات البرمجة وتوليف الكود والتحليل الثابت ، ويسعى جاهداً لمشاركة تجربته مع المنتجات الرقمية مع المستخدمين. في أوقات فراغه ، ينظم اجتماعات نادي TypeScript في سان فرانسيسكو ويحتفظ بمدونة شخصية - performancejs.com . يمكنك العثور على حساب Boris's GitHub على github.com/bcherny .



»يمكن العثور على مزيد من التفاصيل حول الكتاب على الموقع الإلكتروني للناشر

» جدول المحتويات

» مقتطفات



لـ Habitants خصم 25٪ على القسيمة - TypeScript



عند الدفع مقابل النسخة الورقية من الكتاب ، يتم إرسال كتاب إلكتروني إلى البريد الإلكتروني.



All Articles