Skip to content

Commit b97e39b

Browse files
committed
Prefer TypeScript inference over explicit types
- Remove explicit return types from functions where inference works - Remove unnecessary variable type annotations (bigint, symbol) - Add inference-first alternatives to explicit-return-types exercise - Update README with guidance on when to use inference vs explicit types
1 parent d96d87b commit b97e39b

File tree

5 files changed

+46
-18
lines changed

5 files changed

+46
-18
lines changed

exercises/01.primitive-types/04.solution.bigint-and-symbol/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// BigInt and Symbol
22
// Less common but important primitive types
33

4-
// BigInt for large integers
5-
const largeNumber: bigint = 9007199254740993n
6-
const anotherLarge: bigint = 1000000000000000000n
7-
const sum: bigint = largeNumber + anotherLarge
4+
// BigInt for large integers (TypeScript infers bigint from the n suffix)
5+
const largeNumber = 9007199254740993n
6+
const anotherLarge = 1000000000000000000n
7+
const sum = largeNumber + anotherLarge
88

9-
// Symbols are unique
10-
const userId: symbol = Symbol('user-id')
11-
const anotherId: symbol = Symbol('user-id')
12-
const areEqual: boolean = userId === anotherId // false!
9+
// Symbols are unique (TypeScript infers symbol from Symbol())
10+
const userId = Symbol('user-id')
11+
const anotherId = Symbol('user-id')
12+
const areEqual = userId === anotherId // false!
1313

1414
console.log('Large number:', largeNumber)
1515
console.log('Another large:', anotherLarge)

exercises/04.functions/01.solution.parameters-and-returns/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// E-commerce Utility Functions
22
// Creating functions with typed parameters and returns
33

4-
function calculateTax(amount: number, rate: number): number {
4+
function calculateTax(amount: number, rate: number) {
55
return amount * rate
66
}
77

8-
function formatPrice(cents: number): string {
8+
function formatPrice(cents: number) {
99
return `$${(cents / 100).toFixed(2)}`
1010
}
1111

12-
function applyDiscount(price: number, discountPercent: number): number {
12+
function applyDiscount(price: number, discountPercent: number) {
1313
return price - (price * discountPercent) / 100
1414
}
1515

exercises/04.functions/03.solution.explicit-return-types/README.mdx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ Even without seeing the implementation, you know exactly what each function
1515
expects and produces. This is invaluable in larger codebases where you might not
1616
have time to read every function body.
1717

18-
In real projects, teams often have conventions about when to use explicit return
19-
types. A common approach: explicit for exported functions, inference for
20-
internal helpers.
18+
## When to use inference instead
19+
20+
Many teams prefer letting TypeScript infer return types wherever possible:
21+
22+
```ts
23+
function getFullName(firstName: string, lastName: string) {
24+
return `${firstName} ${lastName}` // TypeScript infers: string
25+
}
26+
```
27+
28+
This reduces redundancy since TypeScript already knows the return type from the
29+
implementation. Explicit return types are most valuable when:
30+
31+
- The function is part of a public API boundary
32+
- You want to catch implementation mistakes early
33+
- The inferred type would be too wide (e.g., `string | number` when you want
34+
just `string`)
35+
- State machine functions that must return valid states

exercises/04.functions/03.solution.explicit-return-types/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,16 @@ console.log(isValidEmail('[email protected]')) // true
2020
console.log(isValidEmail('invalid-email')) // false
2121

2222
export { getFullName, parseAge, isValidEmail }
23+
24+
// 🦉 Alternative: Inference-first approach
25+
// In practice, many developers prefer to let TypeScript infer return types.
26+
// This reduces redundancy since TypeScript can figure out the return type:
27+
//
28+
// function getFullName(firstName: string, lastName: string) {
29+
// return `${firstName} ${lastName}` // TypeScript infers: string
30+
// }
31+
//
32+
// Explicit return types are most valuable when:
33+
// - The function is exported as part of a public API
34+
// - You want to catch implementation mistakes early
35+
// - The inferred type would be too wide (e.g., string | number vs string)

exercises/04.functions/04.solution.arrow-functions/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
// Converting between function forms and using implicit returns
33

44
// Arrow function with implicit return
5-
const double = (n: number): number => n * 2
5+
const double = (n: number) => n * 2
66

77
// Arrow function with implicit return (template literal)
8-
const greet = (name: string): string => `Hello, ${name}!`
8+
const greet = (name: string) => `Hello, ${name}!`
99

1010
// Arrow function with explicit return (multiple lines)
11-
const calculateTotal = (prices: number[], taxRate: number): number => {
11+
const calculateTotal = (prices: number[], taxRate: number) => {
1212
const subtotal = prices.reduce((sum, price) => sum + price, 0)
1313
const tax = subtotal * taxRate
1414
return subtotal + tax
1515
}
1616

1717
// Arrow function with implicit return
18-
const isEven = (n: number): boolean => n % 2 === 0
18+
const isEven = (n: number) => n % 2 === 0
1919

2020
// Function using arrow function callbacks
2121
function processNumbers(numbers: number[]) {

0 commit comments

Comments
 (0)