// code snippet
function valueOrDefault(a?: string) {
return a || "the default";
}
mit tslint.json
Konfiguration:
{
"defaultSeverity": "error",
"extends": [
"tslint:all"
]
}
Bericht über 2 Fehler erhalten:
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.
Es werden keine Fehler gemeldet. Ich verwende den logischen Operator ||
, um einen Standardwert für den Parameter bereitzustellen (ich weiß, dass ich eine Standarddeklaration für einen Funktionsparameter verwenden könnte, der Ausschnitt dient nur zur Veranschaulichung des allgemeinen Problems). Es gibt nirgendwo boolean
im Spiel: weder die Eingabe noch die Ausgabe des Ausdrucks.
Die Gedanken? Gebete? Vorschläge, wo/wie man anfangen soll?
@marcind können Sie Beispiele dafür geben, wie es sich anders verhalten sollte als das Drehen der Regel?
Entschuldigung, welcher Teil meiner ursprünglichen Einreichung ist unklar?
Ich denke, mein Punkt ist, dass diese Regel nur in einem "booleschen Kontext" ausgeführt werden sollte, mir fallen zwei Fälle ein:
if
, while
oder for
boolean
zugewiesen.Die Regel sollte nicht ausgeführt werden, wenn ich versuche, einen Standardwert oder eine Kurzschlussauswertung bereitzustellen
const a: string = potentiallyUndefinedString || "the default";
const a: string | undefined = potentiallyUndefinedObject && potentiallyUndefinedObject.getString()
@marcind die Beispiele aus deinem letzten Beitrag würden funktionieren, wenn du die Option "allow-undefined-union"
.
Der andere Teil Ihrer Anfrage sollte eine separate Regel namens strict-boolean-conditions
die nur if
, for
, while
, do ... while
und bedingte prüft Ausdrücke ( x ? y : z
).
Ich kann mir vorstellen, dass es nur die Art des gesamten Zustands und nicht seine Bestandteile überprüft:
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
}
Vielleicht kann dies eine Option für die bestehende Regel anstelle einer neuen Regel sein...
Meiner Meinung nach sollte strict-boolean-expressions
nur den linken Operanden von &&
und ||
prüfen. Diese Operatoren sind (im Wesentlichen) Zucker für Ternäre: a && b
ist gleich a ? b : a
und a || b
ist gleich a ? a : b
. Wenn man so darüber nachdenkt, ist es sehr sinnvoll, das RHS zu ignorieren, und es würde das Verhalten für die Kurzschlussoperatoren mit dem Verhalten für Ternäre in Einklang bringen.
Wenn dann das Ganze ist innerhalb einer if / for / while, strict-boolean-conditions
ins Spiel kommen könnte und prüfen Sie den gesamten Ausdruck. Ich denke, dies würde alle nützlichen Fälle abdecken, und ich könnte diese Regel wieder aktivieren.
Der Code, der dies für mich als Problem markierte, war dieses dokumentierte allgemeine React-Muster :
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 Sein Code
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.
Die Absicht des Ausdrucks hängt vom LHS ab, daher würde mein Vorschlag, den RHS zu ignorieren, auch sein Problem lösen.
Ich stimme zu, dass die Überprüfung des RHS von &&
und ||
ein Fehler ist.
Ich bin auch geneigt, die Schecks für den LHS von &&
, ||
und den Operanden von !
. Diese sollten nur überprüft werden, ob der Ausdruck immer wahr oder immer falsch ist.
Damit bleiben nur die Bedingungen von if
, for
, while
, do ... while
und bedingte Ausdrücke für die strikte Prüfung, um nur boolesche Werte (oder was auch immer sonst konfiguriert ist) zuzulassen ). Gedanken @adidahiya?
Derzeit würde die Aktivierung dieser Regel mit verfügbaren Konfigurationsoptionen tagelange Arbeit mit unserer Codebasis erfordern. :(
Ich habe es aktiviert in der Hoffnung, dass es die implizite Konvertierung von number
, null
oder undefined
in boolean
. Zum Beispiel:
if (!!array.length) { /* ... */ }
md5-d563d6246c0e981c16f8a2b3d7f53974
md5-430ec08bab82330fa4e519419e9ad014
However I find the following uses acceptable:
md5-70351fc6fdb328ee060919d6974e2cf4
```tsx
md5-036fd2ddd516eac8e1379cdcb9ac2b9a
Ich denke, das stimmt mit dem überein, was @marcind vorschlägt .
Ich neige auch dazu, die Checks für den LHS von && zu lockern, || und der Operand von !.
@ajafff würde das if (!!array.length)
oder if (!possiblyNull)
legalisieren?
@ajafff @adidahiya weitere Gedanken hier? Ich bin in genau der gleichen Situation wie @rhys-vdw.
Schamlose Werbung für mein eigenes Projekt:
Seit meiner letzten Aktivität in dieser Ausgabe habe ich meinen eigenen Linter erstellt, das Fimbullinter-Projekt . Lesen Sie die Dokumentation für einen schnellen Start: https://github.com/fimbullinter/wotan/blob/master/packages/wotan/README.md
Es enthält eine Regel no-useless-predicate
, nach der Sie möglicherweise suchen. Es ist eine Kombination aus TSLints strict-type-predicates
und strict-boolean-expressions
, jedoch mit einigen großen Unterschieden:
Im Gegensatz zu TSLints strict-type-predicates
funktioniert es auch ohne --strictNullChecks
und behandelt Typparameter und leere Objekttypen korrekt. (wahrscheinlich nicht so interessant für Leute, die diese Ausgabe abonniert haben)
Der Hauptunterschied zu strict-boolean-expressions
von TSLint besteht darin, dass es nicht erfordert, dass alles ein boolescher
Einige Beispiele:
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
Ich möchte mich mit dem folgenden Anwendungsfall aus meinem tatsächlichen Code einklinken:
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
}
Wie Sie sehen, verwende ich ||
, um Standardwerte anzugeben, wenn der LHS nicht definiert ist. Gibt es eine prägnante Möglichkeit, tslint
verstehen, dass dies strict-boolean-expressions
? Andernfalls bin ich gezwungen, diese Befehle zum Deaktivieren/Aktivieren zu verwenden. (Überraschenderweise ist dies nur ein Problem mit aktivierter Typprüfung und nicht in VSCode.)
Diese Verwendung ist Standard und in JavaScript sehr verbreitet und praktisch und sollte definitiv nicht dazu führen, dass diese Regel fehlschlägt.
IMHO sollten die RHS von &&
und ||
nicht überprüft werden, um einen Kurzschluss zu ermöglichen. Dies sollte das Standardverhalten sein (oder es sollte zumindest eine Option wie allow-any-rhs
). Derzeit kann ich strict-boolean-expressions
, da es in unserer Codebasis viele Kurzschlüsse gibt.
Die Überprüfung des LHS sollte IMHO unverändert bleiben, da die Verwendung von string
oder number
als LHS gefährlich sein kann, siehe dieses Beispiel:
function foo(x: string | number | null) {
return x || defaultValue;
}
Dies ist gefährlich, da viele Entwickler nicht verstehen, dass nicht nur null
sondern auch 0
und ""
defaultValue
zurückgeben.
Ich musste mich mit großen Fehlern in meinem Projekt auseinandersetzen, weil Entwickler nicht berücksichtigten, dass ""
und 0
ebenfalls falsch sind. Diese Art von Code zu verhindern, ist mein primärer Anwendungsfall für strict-boolean-expressions
.
Behoben in https://github.com/palantir/tslint/pull/4159 benötigen Sie nur eine Überprüfung von einem Mitarbeiter.
Hoppla, wollte nur klarstellen, dass eines meiner Beispiele schlecht war:
const x = possiblyUndefined || 5;
Das sollte nicht funktionieren, weil possiblyUndefined
0
könnte, was ein logischer Fehler sein könnte. Sieht so aus , als würde die PR von
enthält für Array ist eine ES7-Funktion.
Sie müssen Ihre ts-Konfiguration ändern, um ES7 oder ESNEXT zu verwenden 🦄
Grüße,
@rimiti Hallo, ich kann nicht herausfinden, worauf du dich
@dobesv Oh, du hast recht, sorry ;)
behoben durch #4159, wird in der nächsten Version verfügbar sein
Hilfreichster Kommentar
Meiner Meinung nach sollte
strict-boolean-expressions
nur den linken Operanden von&&
und||
prüfen. Diese Operatoren sind (im Wesentlichen) Zucker für Ternäre:a && b
ist gleicha ? b : a
unda || b
ist gleicha ? a : b
. Wenn man so darüber nachdenkt, ist es sehr sinnvoll, das RHS zu ignorieren, und es würde das Verhalten für die Kurzschlussoperatoren mit dem Verhalten für Ternäre in Einklang bringen.Wenn dann das Ganze ist innerhalb einer if / for / while,
strict-boolean-conditions
ins Spiel kommen könnte und prüfen Sie den gesamten Ausdruck. Ich denke, dies würde alle nützlichen Fälle abdecken, und ich könnte diese Regel wieder aktivieren.Der Code, der dies für mich als Problem markierte, war dieses dokumentierte allgemeine React-Muster :
@ajafff Sein Code
Die Absicht des Ausdrucks hängt vom LHS ab, daher würde mein Vorschlag, den RHS zu ignorieren, auch sein Problem lösen.