// 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
قيد التشغيل في أي مكان: لا مدخلات أو مخرجات التعبير.
أفكار؟ صلاة؟ اقتراحات حول أين / كيف تبدأ؟
marcind ، هل يمكنك تقديم أمثلة حول كيفية تصرفها بشكل مختلف عن تغيير القاعدة؟
عذرًا ، أي جزء من رسالتي الأولية غير واضح؟
أعتقد أن وجهة نظري هي أن هذه القاعدة يجب أن تعمل فقط في "سياق منطقي" ، ويمكنني التفكير في حالتين:
if
أو while
أو for
boolean
.يجب ألا تعمل القاعدة عندما أحاول تقديم قيمة افتراضية أو تقييم قصر الدائرة
const a: string = potentiallyUndefinedString || "the default";
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 ، سيتوفر في الإصدار القادم
التعليق الأكثر فائدة
في رأيي ، يجب أن يتحقق
strict-boolean-expressions
فقط من المعامل الأيسر لـ&&
و||
. هؤلاء المشغلون (أساسًا) هم سكر لثلاثيات:a && b
يساويa ? b : a
، وa || b
يساويa ? a : b
. عندما تفكر في الأمر بهذه المصطلحات ، فإن تجاهل RHS له معنى كبير ، وسيجعل سلوك مشغلي دائرة القصر متماشياً مع سلوك الثلاثية.بعد ذلك ، إذا كان الأمر برمته داخل if / for / while ، فيمكن أن يلعب
strict-boolean-conditions
ويتحقق من التعبيركان الكود الذي وضع علامة على هذه المشكلة بالنسبة لي هو نمط React الشائع الموثق:
ajafff رمزه لا يمرر
القصد من التعبير مشروط على LHS ، لذا فإن اقتراحي بتجاهل RHS سيحل مشكلته أيضًا.