Tslint: تتعارض قواعد "no-inferably-types" و "typedef"

تم إنشاؤها على ٣ أكتوبر ٢٠١٥  ·  33تعليقات  ·  مصدر: palantir/tslint

أهلا مرة أخرى،

لست متأكدًا مما إذا كانت هذه مشكلة أم قرار تصميم ، ولكن يمكنني رؤية تعارض بين القواعد no-inferrebale-types و typedef .

السابق.

function fn(): void {
    for (let i = 0; i < 100; i++) {
        console.log(i);
    }
}

مقتطف من https://github.com/palantir/tslint/blob/master/docs/sample.tslint.json :

 "typedef": [true, ...],
 "no-inferrable-types": true,

عند تشغيل هاتين القاعدتين ، أحصل على:

error (typedef) test.ts[2, 12]: expected variable-declaration: 'i' to have a typedef

تؤدي إضافة التعليق التوضيحي للنوع number إلى المتغير i بدوره إلى الخطأ التالي:

error (no-inferrable-types) test.ts[2, 14]: LHS type (number) inferred by RHS expression, remove type annotation

هل هناك أي طريقة لتتعايش هاتان القاعدتان مع بعضهما البعض؟

على سبيل المثال ، أريد أن يكون لدي متغيرات غير قابلة للاستدلال تم الإعلان عنها مباشرة بنوع بدائي (كما تقول القاعدة: number ، boolean أو string ) ، لكن من ناحية أخرى ، أريد لفرض أشكال الكتابة على الأنواع غير البدائية.

شكرا،

س.

P1 Enhancement 🌹 R.I.P. 🌹

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

: +1: من الناحية المثالية (imo) أود طريقة لأقول "تتطلب دائمًا محرفًا ، ما لم يكن النوع محتملاً". وهو ما لا أعتقد أنه ممكن الآن.

ال 33 كومينتر

التقاط جيد ، شكرا على التنبيه. أضفت قاعدة no-inferrable-types بدون التفكير في كيفية تعارضها مع قاعدة typedef ، عفوًا! في الوقت الحالي ، أوصي بإيقاف تشغيل أحدهما ، أو استخدام بعض خيارات القاعدة typedef فقط.

على المدى الطويل ، أعتقد أننا نرغب إما في دمج no-inferrable-types في قاعدة typedef أو سنرغب على الأقل في جعل TSLint يكتشف التكوينات المتضاربة مثل وجود القاعدتين.

أواجه نفس المشكلة.
لقد قمت بإيقاف تشغيل أنواع لا يمكن الاستدلال عليها في الوقت الحالي.

نعم نفس الشيء هنا ، أود أن يكون لدي القدرة على أن تتعايش كلتا القاعدتين.
لا أريد أن تبدأ قاعدة typedef إذا كان من الممكن استنتاج نوع المتغير.
على سبيل المثال ، "أنواع لا يمكن الاستدلال عليها" يجب أن يكون لها أولوية على "typedef"

+1

let id: number = 0;
for (let job: string of NAMES_PROFFESSIONS) {
     /** some code */
     id++;
}

(أنواع لا يمكن الاستدلال عليها) نوع LHS (رقم) مستدل عليه بتعبير RHS ، قم بإزالة التعليق التوضيحي من النوع

+1

هل يتضمن تعريفك للأنواع "غير القابلة للاستدلال" تعيينات المُنشئ؟

// BAD (this hurts my eyes to read)
let labels: Map<string, string> = new Map<string, string>();
// GOOD (type is obvious)
let labels = new Map<string, string>();

لكن أيضا...

// BAD (in a diff, it's not obvious what this type is)
let labels = this.buildLabels();
// GOOD
let labels: Map<string, string> = this.buildLabels();

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

let x = 2;
let y;
let z: number;

x = 1;
y = 1;
z = 1;
x = 's'; // Type 'string' is not assignable to type 'number'
y = 's'; // It's OK
z = 's'; // Type 'string' is not assignable to type 'number'

قد يكون خيارًا مفيدًا جدًا للسماح بالتخطي بالتصريح عن نوع المتغيرات التي تمت تهيئتها فقط.

... وفي الحقيقة ليس فقط للأنواع البدائية ، كما يقول pgonzal !
انظر إلى هذا ، إنه أمر فظيع:

const onChange: () => void = () => this.update();

: +1: من الناحية المثالية (imo) أود طريقة لأقول "تتطلب دائمًا محرفًا ، ما لم يكن النوع محتملاً". وهو ما لا أعتقد أنه ممكن الآن.

واجهت هذا وقمت بعمل علامة ignore-params تساعد في حالتي. أرغب في فرض رموز الكتابة لجميع معاملات الأسلوب / الوظيفة حتى عندما يمكن استنتاجها بسهولة.

انظر PR: # 1190 إذا كنت تريد تجربتها

لقد مر وقت طويل منذ إرسال الإصدار الأصلي. هل خيار التوصية في هذه المرحلة لتعطيل no-inferrable-types وتضمين النوع في كل شيء؟ أي شيء آخر يمكنك تجربته وتمكينه والجمع بين كل من no-inferrable-types و typedef يبدو وكأنه اختراق وينتج عنه مجموعة من التحذيرات غير المجدية. على أمل حل أفضل في المستقبل القريب.

corydeppen لاحظ 8 إعجاب على اقتراح englercj أعلاه. ليس من الواضح ما الذي تعنيه كلمة "دمج" في تعليق "يبدو أنه اختراق". إذا كنت تقصد "استخدام معًا في tslint.json ، إذن ، نعم. ولكن" دمج "وسيطة optional-inferrable-types على typedef سيكون رائعًا (على الأقل ، لـ 9 منا).

هل يمكننا الحصول على تحديث حول هذا ، من فضلك؟

أعتقد أن أفضل طريقة للتعامل مع هذا هو إهمال no-inferrable-types ومجرد تمرير عنصر خيار إلى typedef لتجاهل نقص تعريفات النوع إذا كان النوع محتملاً وفقًا لأنماط معينة ، مثل initialized ، initialized primitives ، call signatures وأنماط أخرى من شأنها تلبية احتياجاتنا كمطورين.

بالنسبة لي ، هذا أكثر منطقية ، لأنه يجب أن يكون هناك دائمًا محرف ، ما لم يكن هناك شيء يخبرك ما هو نوع الوظيفة. وسيكون قابلاً للتكوين أيضًا ، لأننا ربما نريد أن يكون للنوع properties الذي تمت تهيئته في الفصل نوعًا لا يمكن استنتاجه ، ولكن ليس لـ call signatures على سبيل المثال.

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

تم فتح هذه المشكلة منذ 3 أكتوبر 2015 - ومنذ ذلك الحين ، قام فريقي بتأليف حوالي 2000 ملف مصدر TypeScript وكلها مزدحمة بالكثير من إقرارات الأنواع.

يقبل typedef التهيئة. لذلك ربما مجرد تكوين آخر لتجاهل تعريف النوع إذا كان النوع لا يمكن الاستدلال عليه ، أي

فقط اكتب في أي مكان لم تتم تهيئته فيه.

يبدو أنه بسبب عدم وجود إجماع واضح حول كيفية التعامل مع هذه القضية ، لم يتم إحراز أي تقدم. تعليق مثال: https://github.com/theia-ide/theia/issues/356#issuecomment -319350833

أظن أننا نتفق جميعًا على أن أي حل أفضل من ترك الأشياء كما هي. إذا كنت تعتقد أن أي تغيير في الوضع الراهن فيما يتعلق بهذه المسألة جيد ، يرجى 👍 هذا التعليق. إذا كنت على دراية كافية بإنشاء علاقات عامة لإصلاح هذه المشكلة ، فيرجى مساعدتنا جميعًا ❤️.

قد تقبل العلاقات العامة من أجل:

  • إضافة خيار إلى typedef يتيح له تجاهل الحالات التي يقول فيها no-inferrable-types عدم تقديم نوع

يقبل typedef التكوين. لذلك ربما يكون مجرد تكوين آخر لتجاهل تعريف النوع إذا كان النوع لا يمكن الاستدلال عليه ، وهذا يعني "اكتب فقط في أي مكان لا تتم تهيئته فيه".

القاعدة typedef مخصصة للأشخاص الذين يحبون وجود تعريفات صريحة للأنواع في قاعدة الأكواد الخاصة بهم. إذا كنت ترغب في أن يكون السلوك أعلاه "اكتب فقط في أي مكان لا تتم فيه تهيئة" ، فمن الأفضل لك تعطيل typedef والتأكد من تمكين noImplictAny كخيار مترجم TypeScript.

هناك أيضًا الحالة الصعبة حيث تحتاج بعض الأشياء التي تمت تهيئتها إلى محرف على أي حال ، كما في المقتطف التالي:

interface Literal {
    field: "value"
}

const literal0 = {
    field: "value",
};
const literal1: Literal = {
    field: "value",
};

const func = (obj: Literal) => { };
func(literal0);  // Error! Type 'string' is not assignable to type '"value"'.
func(literal1);

أيضًا ، بينما نصلح هذا الأمر ، أردت الإشارة إلى أنه من المحتمل وجود بعض القواعد الرائعة للجهات الخارجية ، مثل no-unnecessary-type-annotation (https://github.com/ajafff/tslint-consistent-codestyle/blob/ master / docs / no-unnecessary-type-annotation.md) على سبيل المثال. إذا كان أي شخص يعرف أي قواعد أخرى للجهات الخارجية تعطي السلوك المطلوب ، فيرجى نشرها هنا ويمكننا التوصية بها رسميًا أو اعتمادها في جوهرها إذا كان ذلك منطقيًا.

JKillian شكرًا على التوصية ، أعتقد أن هذا ما أردته حقًا. هناك مشاركة جيدة جدًا حول تجنب النوع any : لا تستخدم "naked any" ، قم بإنشاء "أي واجهة" بدلاً من ذلك.

عن:

interface Literal {
    field: "value"
}

const literal0 = {
    field: "value",
};
const literal1: Literal = {
    field: "value",
};

const func = (obj: Literal) => { };
func(literal0);  // Error! Type 'string' is not assignable to type '"value"'.
func(literal1);

لا أرى كيف يمكن أن يكون هذا سلوكًا غير مرغوب فيه ولا حالة صعبة. تريد التأكد من أن obj له خاصية field بقيمة value ، وحتى عند تهيئة literal0 بخاصية تبدو وكأنها قيود ، يمكنك تعديل ذلك إلى سلسلة أخرى.

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

لدي التكوين التالي:
json "no-inferrable-types": true, "typedef": [true, "call-signature", "parameter"],
وهذا الكود:
javascript private static readonly DEVICE_UID: string = 'device_uid'; private static readonly DEVICE_PLATFORM: string = 'browser'; private static readonly AGENT_DEFAULT_ICON = 'http://localhost:3000/icon.png';

لماذا لا أحصل على خطأ في الإعلانين الأولين؟

sandrocsimas مثير للاهتمام ، ولكن أعتقد أنه خارج الموضوع ؛ AFAICT أن المشكلة لا علاقة لها بهذه القضية. أقترح أن تبدأ مشكلة أخرى (fwiw!).

estaub ، نعم سأفعل. أحصل على نفس السلوك حتى بدون قاعدة typedef.

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

سيكون من الجيد أن يكون لديك قاعدة "تتطلب نوعًا ما عدا الاستنتاج".

@ FiretronP75 كما قال JKillian ، هذا فقط noImplicitAny خيار TSC.

michaeljota شكرًا ، لم أدرك أن الخيار noImplicitAny للمترجم يعطي استثناءات لما لا يمكن توقعه. لا يزال من الجيد وجوده في tslint ، بالنسبة لخيار جعله تحذيرًا بدلاً من كسر التجميع ، ولوجود إشارات تعليق tslint.

أرى سبب أن هذا سيكون شيئًا مطلوبًا ، ولكن بوجود no-unused-variables كمثال ، لا أعتقد أن حالات الاستخدام التي يغطيها TSC سيتم دعمها من قبل فريق TSLint. أعلم أن هذا ليس هو نفسه خطأ _linter_ من خطأ _ compiler_ لكن في النهاية ، كلاهما يدور حول رمز مكتوب بشكل أفضل. الآن مع حلول مثل Webpack أو Parcel التي تتيح لك تجميع التعليمات البرمجية وتشغيلها حتى مع وجود أخطاء TSC ، لا أرى هذه مشكلة حقيقية.

هل تم إصلاح هذا في الإصدار الأخير؟

ما زلت لا أعتقد أن هذا على خارطة الطريق. يجب أن تفكر في استخدام noImplicitAny من TSC

حان وقت TSLint! ☠️

لم يعد TSLint يقبل معظم طلبات الميزات لكل # 4534. راجع print -eslint.io للطباعة للحصول على الطريقة الجديدة اللامعة لتنقيح كود TypeScript الخاص بك باستخدام ESLint . ✨

كان من دواعي سروري فتح المصادر معكم جميعًا!

🤖 صوت صفير! 👉 تم إهمال TSLint 👈 _ (# 4534) _ ويجب عليك التبديل إلى print-eslint ! 🤖

🔒 تم إقفال هذه المشكلة لمنع المزيد من المناقشات غير الضرورية. شكرا لك! 👋

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