// code snippet
function valueOrDefault(a?: string) {
return a || "the default";
}
tslint.json
ꡬμ±:
{
"defaultSeverity": "error",
"extends": [
"tslint:all"
]
}
2κ°μ μ€λ₯μ λν λ³΄κ³ λ°κΈ°:
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()
"allow-undefined-union"
μ΅μ
μ μ¬μ©νλ©΄ λ§μ§λ§ κ²μλ¬Όμ @marcind μμ κ° μλν©λλ€.
μμ²μ λ€λ₯Έ λΆλΆμ if
, for
, while
, do ... while
λ° μ‘°κ±΄λΆλ§ νμΈνλ strict-boolean-conditions
λΌλ λ³λμ κ·μΉμ΄μ΄μΌ ν©λλ€. ννμ( 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 μμ RHSλ‘ μΈν΄ λͺ¨λ κ·μΉ μ΅μ μ΄ νμ±νλ κ²½μ°μλ κ·Έμ μ½λλ λ¦°ν°λ₯Ό μ λ¬νμ§ μμ΅λλ€.
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
쑰건 λ° λΆμΈ(λλ κΈ°ν ꡬμ±λ λͺ¨λ νλͺ©λ§ νμ©νλ μ격ν κ²μ¬λ₯Ό μν 쑰건μ)λ§ λ¨μ΅λλ€. ). @adidahia μκ°?
νμ¬ μ¬μ© κ°λ₯ν κ΅¬μ± μ΅μ μΌλ‘ μ΄ κ·μΉμ νμ±ννλ €λ©΄ μ½λ κΈ°λ°μ μ¬μ©νλ λ° λ©°μΉ μ΄ μμλ©λλ€. :(
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)
ν©λ²νλ©λκΉ?
@ajafff @adidahiya μΆκ° μκ°μ΄ μμΌμ κ°μ? @rhys-vdwμ λκ°μ μν©μ λλ€.
λ΄ μμ μ νλ‘μ νΈλ₯Ό λ»λ»νκ² κ΄κ³ :
μ΄λ² νΈμ λ§μ§λ§ νλ μ΄νλ‘ μ λ Fimbullinter νλ‘μ νΈμΈ μ λ§μ λ¦°ν°λ₯Ό λ§λ€μμ΅λλ€. λΉ λ₯Έ μμμ μν λ¬Έμ μ½κΈ°: 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
μ¬μ©ν μ μμ΅λλ€.
string
λλ number
λ₯Ό LHSλ‘ μ¬μ©νλ κ²μ μνν μ μμΌλ―λ‘ LHSλ₯Ό κ·Έλλ‘ IMHOλ‘ νμΈν΄μΌ ν©λλ€. λ€μ μλ₯Ό μ°Έμ‘°νμΈμ.
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 μ PRμ΄ μ¬κΈ°μμ μλνλ κ² κ°μ΅λλ€.
λ°°μ΄μ λν ν¬ν¨μ ES7 κΈ°λ₯μ
λλ€.
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 μμ RHSλ‘ μΈν΄ λͺ¨λ κ·μΉ μ΅μ μ΄ νμ±νλ κ²½μ°μλ κ·Έμ μ½λλ λ¦°ν°λ₯Ό μ λ¬νμ§ μμ΅λλ€.
ννμ μλλ LHSμ λν 쑰건λΆμ΄λ―λ‘ RHSλ₯Ό 무μνμλ λ΄ μ μμ κ·Έμ λ¬Έμ λ ν΄κ²°ν κ²μ λλ€.