Typescript: اقتراح: عدم السماح بالاستخدام قبل التعريف

تم إنشاؤها على ١٥ يوليو ٢٠١٤  ·  29تعليقات  ·  مصدر: microsoft/TypeScript

يجب أن يصدر المترجم خطأً عندما تستخدم التعليمات البرمجية قيمًا قبل إمكانية تهيئتها.

// Error, 'Derived' declaration must be after 'Base'
class Derived extends Base { }
class Base { }
Bug

التعليق الأكثر فائدة

فقط لذكر أننا تعرضنا للعض من هذا اليوم ، واستغرق الأمر بعض الوقت لمعرفة ما كان يجري.

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

عدم خوض المناقشة بأكملها ، ولكن كإسعافات أولية يبدو أن تحذير المترجم سيساعد. فقط لدينا 2

ال 29 كومينتر

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

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

هل يجب أن نجعل هذا اقتراحًا جديدًا؟ هذا هو السبب في أنني أستخدم حاليًا وحدات AMD بدلاً من وحدات TypeScript الداخلية ؛ يحدد برنامج التحويل البرمجي RequireJS ترتيب تسلسل الوحدة النمطية المناسب باستخدام التبعيات التي أحددها عبر قاعدة الكود (باستخدام require() ).

ربط رقم 274. نحن بحاجة إلى تحديد قواعد ونطاق ذلك

تبدو الحالة الممتدة مرشحًا جيدًا للتدقيق المعجمي ؛ نحتاج فقط إلى التأكد من أن الصنف الأساسي يأتي قبل الصنف المشتق. هل هناك حالات أخرى يجب النظر فيها؟

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

أعتقد أن حالة الملفات المتعددة أكثر إثارة للاهتمام وفائدة من وجهة نظر مشروع / صيانة كبير (وهو الهدف الظاهري للنص المطبوع ، بعد كل شيء).

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

فيما يلي بعض العبارات التي أعتقد أنها ستضمن الطلب:

class X extends Y {} // ensure Y is defined in prior file
module { new X(); } // ensure X is defined in prior file
class S { static z = new Z(); } // ensure Z is defined in prior file

يمكننا أيضًا توسيع هذا ليشمل الدوال والمتغيرات التي يتم تعريفها قبل الاستخدام ، وليس فقط الفئات.

PS لدي نموذج أولي.

لا أعتقد أن هناك أي نية لمحاولة إعادة ترتيب البث نيابةً عنك ، فقط لإعطاء الأخطاء حيثما أمكننا للأشياء التي من المؤكد أنها ستفشل في وقت التشغيل.

دان ، أنا أتفق معك بشأن إعادة الترتيب داخل ملف واحد ، ولكن عندما يتم دمج ملفات متعددة باستخدام --out ، يكون للمجمع التحكم في ترتيب الإرسال وأفضل أن يعمل الترتيب الذي يختاره.

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

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

بالنسبة للتنفيذ ، فقد أضفت مؤخرًا التحقق من الأمر المعجمي باستخدام Let and Const ، ويمكن استخراجه كتحقق عام واستخدامه في هذه الحالات المختلفة. يمكنك العثور عليها هنا:
https://github.com/Microsoft/TypeScript/blob/master/src/compiler/checker.ts#L329

نحن بحاجة إلى تحديد الحالات التي نتحقق فيها بوضوح ، وسيكون العلاقات العامة موضع ترحيب بالتأكيد :)

نعم ، أوافق على أننا لا نريد إعادة الترتيب داخل ملف واحد مطبوع ، ولكن في حالة الملف --out ، لم يتم تحديد الترتيب من قبل المستخدم ، لذا ، مرة أخرى ، أفضل أن يبذل المترجم قصارى جهده اختر طلبًا يعمل.

يعد رفع الوظيفة مثالًا جيدًا على الأماكن التي لا نحتاج إلى الاهتمام بها في حالة الملف الفردي ، ولكن حيث يمكن أن يكون التجميع إلى ملفات متعددة واختيار تسلسل لتضمينها في ملف .html أمرًا غير مهم بالنسبة للإنسان. المتغيرات التي تكون غير معرّفة عند الاستخدام هي مثال رائع على المكان الذي يمكن أن يقدم فيه المترجم سلوكًا غير متوقع بسبب التغيير في خطوط /// <reference> .

ولكن في حالة الملف --out ، لا يتم تحديد الترتيب من قبل المستخدم

هذا ليس هو الحال حقا. لدينا قواعد بسيطة للغاية هنا - استخدم الترتيب الضمني بعلامات reference وترتيب الملفات في سطر الأوامر. في كلتا الحالتين ، يقدم لنا المستخدم طلبًا. جعل المترجم يتجاهل الأمر الذي قدمه المستخدم هو طريق خطير للنزول. ماذا لو قرر المترجم أمرًا مختلفًا عن الترتيب الذي تفضله؟ كيف يمكنك تجاوز ذلك؟ ماذا لو كسر أحد الطلبات فئتين وأمر آخر يكسر متغيرين؟

ثم لا ينبغي لنا تغيير الترتيب ولكن هل ينبغي لنا على الأقل (لدينا خيار) تحذير المستخدم من أن الترتيب الذي يستخدمه المترجم ربما يكون خاطئًا؟

نعم. لا يجب أن نطلب ، ولكن الخطأ بدلاً من ذلك.

ما هو المصطلح الصحيح في TypeScript للفئات التكرارية المتبادلة؟ A declare class قبل التعريف الفعلي؟

إذا كانت فصولك تشير ببساطة إلى بعضها البعض في نظام النوع أو في طرق المثيل ، فهذه ليست مشكلة. النمط "العودي المتبادل" الوحيد الذي يمثل مشكلة هو هذا النمط:

class Alpha {
    static myFriendBeta = new Beta();   
}

class Beta {
    static myFriendAlpha = new Alpha(); 
}

يمكنك إعادة كتابة هذا على هيئة كتلة:

class Alpha {
}

class Beta {
    static myFriendAlpha = new Alpha();
}

module Alpha {
    export var myFriendBeta = new Beta();
}

حسنًا ، ما هي القواعد التي نرغب في تنفيذها كجزء من هذه المشكلة إلى جانب "يجب تحديد الفئة الأساسية بشكل معجمي قبل الفئة المشتقة"؟

عدم السماح بإعادة توجيه المراجع إلى أعضاء الوحدة الداخلية ، على سبيل المثال

var x = M.fn(); // Should error
module M {
    export function fn() {}
}

عدم السماح بإعادة توجيه المراجع إلى أعضاء التعداد

var x = E.A; // Should error
enum E { A }

IMO نطاق هذه المشكلة محدود إلى حد ما كما هو الحال لأن الأشخاص لا يحددون عادةً كل التعليمات البرمجية الخاصة بهم في ملف واحد: من المرجح أن توجد الفئة الأساسية في ملف منفصل عن الفئة المشتقة.

أقترح أن ما يلي من sparecycles يجب أن يكون أيضًا جزءًا من حل هذه المشكلة:

ثم لا ينبغي لنا تغيير الترتيب ولكن هل ينبغي لنا على الأقل (لدينا خيار) تحذير المستخدم من أن الترتيب الذي يستخدمه المترجم ربما يكون خاطئًا؟

يجب أن يتضمن "الطلب الذي يستخدمه المترجم" الترتيب المحدد في tsconfig .

عندما تكون الفئة الأساسية والفئات المشتقة في نفس الملف ، فإن المشكلة ليست بهذا السوء: سيتعطل البرنامج عند بدء التشغيل وسيغير المبرمج الترتيب في هذا الملف وستكون المشكلة _ fixed_.

حالة الملفات المتعددة هي المكان الذي يجب على المترجم أن يحذر فيه عند تسلسل عدة ملفات بترتيب مشكوك فيه ، لأن هذا الترتيب يمكن أن يتغير لأسباب خفية.

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

حسنًا ، لا توجد مشكلة في الملفات المشار إليها بشكل متبادل ، إذا اشتملت A.ts على إشارات متبادلة B.ts و X.ts على A.ts ، فسيكون ترتيب الإخراج [B ، A ، X] ، وإذا كان يشير إلى B.ts سيكون الترتيب [A ، B ، X]. (ولكن قد يعمل واحد فقط من هذه الأوامر في وقت التشغيل.) وهذا يجعل الأشياء هشة ، حيث أن التجميع سينجح بنفس القدر إذا تمت الإشارة إلى أي من B أو A.

الحل الخاص بي لمشكلة نظام الفصل المشتق من القاعدة: أضف index.ts للتسلسل الهرمي للفئات الخاصة بي وقم بتضمين جميع الفئات المشتقة في هذا الملف ، متبوعة بالفئة الأساسية. هذا يضمن أن الناتج سيضع الفئة الأساسية أولاً. (غير بديهي تمامًا!). لقد وجدت أنه إذا أشرت مباشرة إلى الملفات التي أردتها ، فسينتهي الأمر بإنشاء الفئة الأساسية بعد الفئة المشتقة.

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

(لقد تم تنفيذ هذا حاليًا لإنشاء قائمة .js المضمنة تلقائيًا في مشروع Visual Studio / Typescript نظرًا لأننا نستخدم إخراج ملفات متعددة (أسهل في التصحيح). لكن الكود موجود في C # كمهمة مضمنة. إذا كان هناك هو اهتمام سأطلبه إذا كان بإمكاني مشاركته. إنه في الأساس تشغيلان لخوارزمية CC في Tarjan.)

كلا التحذير عندما يكون ترتيب الانبعاث خاطئًا وتثبيت ترتيب الانبعاث بتوجيه صريح من شأنه أن يقطع شوطًا طويلاً نحو جعل الكتابة المطبوعة لغة قابلة للتطبيق للمشاريع الكبيرة ... نعم؟

واجهت هذه المشكلة بشكل متكرر إلى حد ما مع قاعدة التعليمات البرمجية الصغيرة الخاصة بي (حوالي 80 ملفات .ts). من الناحية المثالية ، أود ألا يكون لدي أي علامات <reference> في الجزء العلوي من أي من ملفاتي ، ويمكن للمترجم أن يعمل بها بالكامل.

يحتوي تطبيقي على ملف واحد فقط يقوم بإنشاء الطبقات وينفذ التطبيق (جذر التكوين الخاص بي) ، وبعض الملفات التي تضيف امتدادات (مثل إضافة Array.prototype.distinct ) والباقي عبارة عن تعريفات للفئة / الواجهة.

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

هل يمكن وضع علامة على المترجم --looseSorting ؟ يبدو وكأنه ميزة مرغوبة إلى حد ما.

في إصدار إعلان الفئة في ES6 ، نقوم بتعيين خاصية ثابتة بعد إعلان الفئة. هذا يجعل الإشارة إلى خاصية ثابتة للفئة في اسم الخاصية المحسوبة تصبح use قبل تعريف.

المنبعثة من JS:

class C {
    [C.p] () {}  // Use before definition
    [C.p+ C.e]() {}  // Use before definition
    [D.f] () {}  // Use before definition
}
C.p = 10;
C.e = 20;

class D {
}
D.f = "hi";

نريد فقط التحذير من هذا الخطأ في حالتين: تشير أسماء الخصائص المحسوبة إلى الخاصية الثابتة للفئة ، أو تشير إلى خاصية الفئة الأخرى المحددة أدناه.

المثال التافه الذي كنا نلعب به اليوم ، فقط لتضمينه في أي اختبارات:

function f() {
    function g() {
        i = 10;
    }

    let i = 20;
    g();
}

سيكون من الجيد الحصول على تباديل استخدامات / تعريفات g حوالي i .

لا تنس التفكير في الوظائف المحددة في نطاق الكتلة. هذا سلوك غير محدد وفقًا لمعيار JavaScript ، وأنا أعلم على الأقل أن Firefox و Chrome يختلفان في تنفيذهما.

على سبيل المثال:

function f() {
    if (true) {
        g(); // iirc, g executes in Chrome, and is undefined in Firefox
        function g() {
        }
        g(); // works in both browsers
    }
}

فقط لذكر أننا تعرضنا للعض من هذا اليوم ، واستغرق الأمر بعض الوقت لمعرفة ما كان يجري.

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

عدم خوض المناقشة بأكملها ، ولكن كإسعافات أولية يبدو أن تحذير المترجم سيساعد. فقط لدينا 2

أجد أنه من السخف أن TS لا تدعم هذه الميزة خارج الصندوق. التشويش الذي يسببه مشابه لاستخدام JS القياسي. أيضا ، الطرق الافتراضية ، أي شخص؟

MrGuardian تم إصلاح repro الموصوف في OP. ربما يمكنك توضيح مشكلة جديدة أو مشكلة حالية تصف المشكلة التي تواجهها بشكل أفضل؟

(# 12673) إليك حالتين أخريين يجب أن تكون IMO أخطاء:

""
اختبار فئة
{
_b = this._a ؛ // غير محدد ، لا يوجد خطأ / تحذير
_a = 3 ؛

static _B = Test._A; // undefined, no error/warning
static _A = 3;

method()
{
    let a = b; // Block-scoped variable 'b' used before its declaration
    let b = 3;
}

}
""

Spongman هل يمكنك تسجيل ذلك في مشكلة منفصلة من فضلك؟ شكر!

12673

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

siddjain picture siddjain  ·  3تعليقات

MartynasZilinskas picture MartynasZilinskas  ·  3تعليقات

zhuravlikjb picture zhuravlikjb  ·  3تعليقات

jbondc picture jbondc  ·  3تعليقات

blendsdk picture blendsdk  ·  3تعليقات