Problem overview
The method legalAge receives a number age and returns true if it is a legal age, at least 18, and false otherwise. The lesson asks for it in a single line, with no if or else.
Approach: a comparison is already a boolean
The first version most learners write looks like this:
class Solution {
legalAge(age: number): boolean {
if (age >= 18) {
return true;
} else {
return false;
}
}
}
It is correct, but it says the same thing twice. The expression age >= 18 already evaluates to true or false. The if reads that value and then produces the very same value by hand. If the condition is true, the method returns true, and if it is false, the method returns false. Returning the condition itself does exactly that.
The rule is general: when each branch of an if/else returns the matching boolean literal, the whole statement can be replaced by return followed by the condition. If the branches are the other way round, returning false when the condition holds, return the negation of the condition instead, with !, or flip the comparison.
Step by step
- Find the condition. Legal age means at least 18, so the condition is
age >= 18. The operator is>=, not>, so that an age of exactly 18 counts. - Return it directly. Put the comparison after
return. The method gives back whatever the comparison evaluates to.
The solution in TypeScript
class Solution {
legalAge(age: number): boolean {
return age >= 18;
}
}
Some TypeScript details about this code:
- The return type matches. A comparison has the type
boolean, which is what the declaration: booleanpromises. The annotation is checked at compile time and erased from the JavaScript. - No parentheses needed.
returntakes the whole expression that follows it, soreturn age >= 18;returns the result of the comparison. You may writereturn (age >= 18);if you find it easier to read. - The ternary version is also redundant.
return age >= 18 ? true : false;is one line, but it repeats the same mistake in a different shape. The conditional operator is for choosing between values that are not already the condition.
The inverse case
The same idea works when the branches are the other way round. This version returns false for adults:
function isMinor(age: number): boolean {
if (age >= 18) {
return false;
} else {
return true;
}
}
The returned value is always the opposite of the condition, so it reduces to return !(age >= 18); or, more readable, return age < 18;. Both give the same result for every number except NaN, where NaN < 18 is false and !(NaN >= 18) is true.
Testing
const solution = new Solution();
console.log(solution.legalAge(17));
console.log(solution.legalAge(18));
console.log(solution.legalAge(40));
false
true
true
The boundary value 18 is the one worth testing. If it prints false, the comparison uses > instead of >=.
Edge cases and common mistakes
- Off by one at 18. Using
> 18excludes exactly 18, and>= 19does too. "At least 18" means 18 is included. - Keeping an
elseafter a return. Writingif (age >= 18) { return true; } return false;is shorter than the first version but still longer than needed. - Printing instead of returning.
console.log(age >= 18)shows the value on screen, but the method must hand it back to the caller withreturn. - Not a number. If a value that is not a number reaches the method at run time, for example
NaN, the comparison isfalse:NaN >= 18is never true. The type annotation does not prevent this, because it is erased.
Key takeaways
- Comparisons produce booleans, and booleans can be returned like any other value.
- If an
if/elseonly returnstrueorfalseaccording to its condition, return the condition. - The shorter version means fewer places for a bug to hide, and it reads like the rule it implements.