Tslint: يجب ألا يتم تنشيط التعبيرات المنطقية الصارمة للعوامل المنطقية المستخدمة في سياق غير منطقي

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

تقرير الشوائب

  • __ إصدار TTSLint__: 5.7.1
  • __نسخة TypeScript__: 2.5.3
  • __جري TSLint عبر__: CLI

يتم فحص كود TypeScript

// code snippet
function valueOrDefault(a?: string) {
  return a || "the default";
}

بتهيئة tslint.json :

{
  "defaultSeverity": "error",
  "extends": [
      "tslint:all"
  ]
}

السلوك الفعلي

الحصول على تقرير عن خطأين:
strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it could be undefined. Only booleans are allowed.
strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it is always truthy. Only booleans are allowed.

سلوك متوقع

لم يتم الإبلاغ عن أي أخطاء. أنا أستخدم عامل التشغيل المنطقي || لتقديم قيمة افتراضية للمعامل (أعلم أنه بإمكاني استخدام إعلان افتراضي لمعامل الوظيفة ، المقتطف هو فقط لتوضيح المشكلة العامة). لا يوجد boolean قيد التشغيل في أي مكان: لا مدخلات أو مخرجات التعبير.

Fixed Bug

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

في رأيي ، يجب أن يتحقق strict-boolean-expressions فقط من المعامل الأيسر لـ && و || . هؤلاء المشغلون (أساسًا) هم سكر لثلاثيات: a && b يساوي a ? b : a ، و a || b يساوي a ? a : b . عندما تفكر في الأمر بهذه المصطلحات ، فإن تجاهل RHS له معنى كبير ، وسيجعل سلوك مشغلي دائرة القصر متماشياً مع سلوك الثلاثية.

بعد ذلك ، إذا كان الأمر برمته داخل if / for / while ، فيمكن أن يلعب strict-boolean-conditions ويتحقق من التعبير

كان الكود الذي وضع علامة على هذه المشكلة بالنسبة لي هو نمط React الشائع الموثق:

function Foo(props: { showToggle: boolean }) {
  return <div>{props.showToggle && <Toggle />}</div>;
}
ERROR: 2:36 strict-boolean-expressions This type is not allowed in the operand for the '&&' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.

ajafff ​​رمزه لا يمرر

export function valueOrDefault(a?: string) {
  return a || "the default";
}
"strict-boolean-expressions": [true, "allow-null-union", "allow-undefined-union", "allow-string", "allow-number", "allow-mix"]
ERROR: 2:15 strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.

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

ال 18 كومينتر

أفكار؟ صلاة؟ اقتراحات حول أين / كيف تبدأ؟

marcind ، هل يمكنك تقديم أمثلة حول كيفية تصرفها بشكل مختلف عن تغيير القاعدة؟

عذرًا ، أي جزء من رسالتي الأولية غير واضح؟

أعتقد أن وجهة نظري هي أن هذه القاعدة يجب أن تعمل فقط في "سياق منطقي" ، ويمكنني التفكير في حالتين:

  1. تستخدم في if أو while أو for
  2. مخصص لمتغير مكتوب كـ boolean .

يجب ألا تعمل القاعدة عندما أحاول تقديم قيمة افتراضية أو تقييم قصر الدائرة

  1. const a: string = potentiallyUndefinedString || "the default";
  2. const a: string | undefined = potentiallyUndefinedObject && potentiallyUndefinedObject.getString()

marcind ستعمل الأمثلة من مشاركتك الأخيرة إذا كنت تستخدم الخيار "allow-undefined-union" .

يجب أن يكون الجزء الآخر من طلبك عبارة عن قاعدة منفصلة باسم strict-boolean-conditions والتي تتحقق فقط من if ، for ، while ، do ... while و مشروطة التعبيرات ( x ? y : z ).
يمكنني أن أتخيل أنه سيتحقق فقط من نوع الحالة بأكملها وليس مكوناتها:

function foo(a: boolean, b?: boolean) {
    if (b || a) {} // passes, result is always boolean
    if (b && a) {} // fails, result is boolean | undefined
    if (a || b) {} // fails, result is boolean | undefined
    if (a || !!b) {} // passes
}

ربما يمكن أن يكون هذا خيارًا للقاعدة الحالية بدلاً من قاعدة جديدة ...

في رأيي ، يجب أن يتحقق strict-boolean-expressions فقط من المعامل الأيسر لـ && و || . هؤلاء المشغلون (أساسًا) هم سكر لثلاثيات: a && b يساوي a ? b : a ، و a || b يساوي a ? a : b . عندما تفكر في الأمر بهذه المصطلحات ، فإن تجاهل RHS له معنى كبير ، وسيجعل سلوك مشغلي دائرة القصر متماشياً مع سلوك الثلاثية.

بعد ذلك ، إذا كان الأمر برمته داخل if / for / while ، فيمكن أن يلعب strict-boolean-conditions ويتحقق من التعبير

كان الكود الذي وضع علامة على هذه المشكلة بالنسبة لي هو نمط React الشائع الموثق:

function Foo(props: { showToggle: boolean }) {
  return <div>{props.showToggle && <Toggle />}</div>;
}
ERROR: 2:36 strict-boolean-expressions This type is not allowed in the operand for the '&&' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.

ajafff ​​رمزه لا يمرر

export function valueOrDefault(a?: string) {
  return a || "the default";
}
"strict-boolean-expressions": [true, "allow-null-union", "allow-undefined-union", "allow-string", "allow-number", "allow-mix"]
ERROR: 2:15 strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.

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

أوافق على أن التحقق من RHS لـ && و || خطأ.


أنا أميل أيضًا إلى تخفيف الشيكات الخاصة بـ LHS لـ && و || والمعامل ! . يجب التحقق من هذه فقط ما إذا كان التعبير دائمًا صحيحًا أم زائفًا دائمًا.
هذا يترك فقط شروط if ، for ، while ، do ... while والتعبيرات الشرطية للفحص الصارم للسماح فقط بالقيم المنطقية (أو أي شيء آخر تم تكوينه ). خواطرadidahiya؟

يتطلب تمكين هذه القاعدة حاليًا مع خيارات التكوين المتاحة أيامًا من العمل مع قاعدة التعليمات البرمجية الخاصة بنا. :(

لقد قمت بتمكينه على أمل منع التحويل الضمني لـ number أو null أو undefined إلى boolean . على سبيل المثال:

if (!!array.length) { /* ... */ }


md5-d563d6246c0e981c16f8a2b3d7f53974





md5-430ec08bab82330fa4e519419e9ad014




However I find the following uses acceptable:



md5-70351fc6fdb328ee060919d6974e2cf4



```tsx


md5-036fd2ddd516eac8e1379cdcb9ac2b9a


وأعتقد أن هذا يتفق مع ماmarcind يقترح .

أنا أميل أيضًا إلى الاسترخاء في الشيكات الخاصة بـ LHS لـ &&، || ومعامل!

ajafff هل هذا if (!!array.length) أو if (!possiblyNull) ؟

ajafffadidahiya هل من أفكار أخرى هنا؟ أنا في نفس الموقف تمامًا مثل @ rhys-vdw.

أعلن بلا خجل عن مشروعي الخاص:
منذ آخر نشاط لي في هذا العدد ، قمت بإنشاء linter الخاص بي ، https://github.com/fimbullinter/wotan/blob/master/packages/wotan/README.md

يحتوي على قاعدة no-useless-predicate ، والتي قد تكون ما تبحث عنه. إنه مزيج من TSLint strict-type-predicates و strict-boolean-expressions ، لكن مع بعض الاختلافات الرئيسية:

على عكس TSLint strict-type-predicates يعمل أيضًا بدون --strictNullChecks ويتعامل بشكل صحيح مع معلمات النوع وأنواع الكائنات الفارغة. (ربما لا يكون مثيرًا للاهتمام للأشخاص المشتركين في هذه المشكلة)
الاختلاف الرئيسي في TSLint strict-boolean-expressions هو أنه لا يتطلب أن يكون كل شيء منطقيًا (لا يكتشف الإكراه الضمني). إنه يتطلب فقط أن تكون كل حالة صادقة وخطيرة.

بعض الأمثلة:

if (0) {} // error, always falsy
if (1) {} // error, always truthy
declare let array: string[];
if (array.length) {} // no error
if (!array.length) {} // no error
if (!!array.length) {} // no error
if (array.length === undefined) {} // error, condition is always false
if (!!false) {} // 2 errors, because of the double negation of an always falsy value

declare let someString: string;
return someString || 'some default string'; // no error, because 'someString' might be falsy

declare const foo: 'bar' | 'baz';
return foo || 'bas'; // error, 'foo' is always truthy

declare let optionalFunction: (() => void) | undefined;
optionalFunction && optionalFunction(); // no error

أرغب في التناغم مع حالة الاستخدام التالية من الكود الفعلي:

export interface ILoggingRule {
    readonly isFinal?: boolean;
    readonly loggerNamePattern?: string;
    readonly maxLogLevel?: LogLevel;
    readonly minLogLevel?: LogLevel;
    readonly target: Target;
}

// ...

/**
 * Creates an instance of LoggingRule.
 * <strong i="6">@param</strong> options Configuration options of the logging rule.
 */
public constructor(options: ILoggingRule) {
    // tslint:disable:strict-boolean-expressions
    this.isFinal = options.isFinal || false;
    this.loggerNamePattern = options.loggerNamePattern || "*";
    this.maxLogLevel = options.maxLogLevel || LogLevel.Fatal;
    this.minLogLevel = options.minLogLevel || LogLevel.Trace;
    this.target = options.target;
    // tslint:enable:strict-boolean-expressions
}

كما ترى ، أستخدم || للإشارة إلى القيم الافتراضية إذا كان LHS غير محدد. هل هناك أي طريقة موجزة تجعل tslint يفهم أن هذا لا يلتزم بـ strict-boolean-expressions ؟ وإلا فأنا مجبر على استخدام أوامر التعطيل / التمكين هذه. (والمثير للدهشة أن هذه مشكلة فقط في تمكين التحقق من النوع وليس في VSCode.)

هذا الاستخدام قياسي وشائع للغاية وملائم في JavaScript ، وبالتأكيد يجب ألا يؤدي إلى فشل هذه القاعدة.

لا ينبغي فحص IMHO RHS لـ && و || ، للسماح بتقصير الدائرة. يجب أن يكون هذا هو السلوك الافتراضي (أو على الأقل يجب أن يكون هناك خيار مثل allow-any-rhs ). حاليًا ، لا يمكنني استخدام strict-boolean-expressions ، نظرًا لوجود الكثير من الدوائر القصيرة في قاعدة الشفرة الخاصة بنا.

يجب أن يظل فحص LHS كما هو IMHO ، نظرًا لأن استخدام string أو number مثل LHS يمكن أن يكون خطيرًا ، انظر هذا المثال:

function foo(x: string | number | null) {
  return x || defaultValue;
}

هذا أمر خطير لأن العديد من المطورين سيفشلون في فهم أنه ليس فقط null ولكن أيضًا 0 و "" سيتسبب في إرجاع defaultValue .

لقد اضطررت للتعامل مع الأخطاء الرئيسية في مشروعي ، نظرًا لفشل المطورين في مراعاة أن "" و 0 هي أيضًا خاطئة. إن منع هذا النوع من الكود هو حالة الاستخدام الأساسية الخاصة بي لـ strict-boolean-expressions .

تم الإصلاح في https://github.com/palantir/tslint/pull/4159 فقط بحاجة إلى مراجعة من أحد المتعاونين.

عفوًا ، أردت فقط توضيح أن أحد الأمثلة التي قدمتها كان سيئًا:

const x = possiblyUndefined || 5;

لا ينبغي أن يعمل ذلك لأن possiblyUndefined قد يكون 0 والذي قد يكون خطأ منطقيًا. يبدو أن العلاقات العامة dobesv ستعمل هنا.

يشمل للمصفوفة هي ميزة ES7.
تحتاج إلى تغيير تكوين ts لاستخدام ES7 أو ESNEXT 🦄

تحياتي ، 🚀

rimiti مرحبًا ، لا يمكنني معرفة ما تشير إليه ، هل أنت متأكد من نشر هذا التعليق في الموضوع الصحيح؟

dobesv أوه ، أنت على حق آسف ؛)

تم إصلاحه بواسطة # 4159 ، سيتوفر في الإصدار القادم

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