Here is a slice of the BookNest cart in both languages; the TypeScript version, compiled with tsc and run with node, prints the same Total: 32.66:
interface Book { title: string; price: number; inStock: boolean }
const books: Book[] = [
{ title: "The Quiet Harbor", price: 14.99, inStock: true },
{ title: "Salt and Saffron", price: 24.0, inStock: false },
{ title: "Gardens in Glass", price: 21.3, inStock: true },
];
const total = (list: Book[], discount = 0): number =>
list.filter((b) => b.inStock).reduce((sum, b) => sum + b.price, 0) * (1 - discount);
console.log(`Total: ${total(books, 0.1).toFixed(2)}`);data class Book(val title: String, val price: Double, val inStock: Boolean)
val books = listOf(
Book("The Quiet Harbor", 14.99, true),
Book("Salt and Saffron", 24.0, false),
Book("Gardens in Glass", 21.3, true),
)
fun total(list: List<Book>, discount: Double = 0.0): Double =
list.filter { it.inStock }.sumOf { it.price } * (1 - discount)
fun main() {
println("Total: ${"%.2f".format(total(books, discount = 0.1))}")
println(books[0] == Book("The Quiet Harbor", 14.99, true))
}Output
Total: 32.66 true
Kotlin's return type follows the parameter list, and = introduces a single-expression body. A lambda lives in braces; as the last argument it moves outside the parentheses, and it names its single parameter. discount = 0.1 is a named argument, which TypeScript lacks. A data class needs no new and generates toString(), equals() and copy() (Data Classes), hence the true: Kotlin's == compares contents, and === tests identity, the only comparison JavaScript's === makes between objects.