Skip to content

Instantly share code, notes, and snippets.

@helje5
Created June 17, 2025 14:17
Show Gist options
  • Save helje5/4da7f58649ebeb842b9acd7215fae1c4 to your computer and use it in GitHub Desktop.
Save helje5/4da7f58649ebeb842b9acd7215fae1c4 to your computer and use it in GitHub Desktop.
Properly insane JavaScript Operators for Swift
func ===<T: Equatable>(lhs: T, rhs: T) -> Bool { lhs == rhs }
func ===(lhs: some Equatable, rhs: some Equatable) -> Bool { false }
func ==(lhs: Double, rhs: some Collection & StringProtocol) -> Bool {
lhs == (rhs.isEmpty ? 0.0 : (Double(rhs) ?? .nan))
}
func ==(lhs: some Collection&StringProtocol, rhs: Double) -> Bool { rhs == lhs }
func ==(lhs: some BinaryInteger, rhs: some StringProtocol&Collection) -> Bool {
Double(lhs) == rhs
}
func ==(lhs: some StringProtocol&Collection, rhs: some BinaryInteger) -> Bool {
rhs == lhs
}
func ==<T>(lhs: Double, rhs: T) -> Bool {
if let rhs = rhs as? any Collection { // should do: "toPrimitive"
lhs == rhs.map { String(describing: $0) }.joined(separator: ",")
}
else { lhs == String(describing: rhs) }
}
func ==<T>(lhs: T, rhs: Double) -> Bool { rhs == lhs }
func ==<T>(lhs: some BinaryInteger, rhs: T) -> Bool { Double(lhs) == rhs }
func ==<T>(lhs: T, rhs: some BinaryInteger) -> Bool { rhs == lhs }
func ==<T>(lhs: Bool, rhs: T) -> Bool { (lhs ? 1.0 : 0.0) == rhs }
func ==<T>(lhs: T, rhs: Bool) -> Bool { rhs == lhs }
func ==(lhs: some Collection, rhs: some Collection) -> Bool { false }
func ==(lhs: some Collection, rhs: some Collection & StringProtocol) -> Bool {
lhs.map { String(describing: $0) }.joined(separator: ",") == String(rhs)
}
func ==(lhs: some Collection & StringProtocol, rhs: some Collection) -> Bool {
rhs == lhs
}
prefix func !(value: some Collection) -> Bool { false } // ![] => false!
print(#""" == 0 => "#, "" == 0) // true
print(#""0" == 0 => "#, "0" == 0) // true
print(#"0 == "0" => "#, 0 == "0") // true
print(#"false == "0" => "#, false == "0") // true
print(#"false == [] => "#, false == []) // true
print(#"[] == ![] => "#, [] == ![]) // true
print(#"[1] == 1 => "#, [1] == 1) // true
print(#"[] == [] => "#, [] == []) // false
print(#"[] == "" => "#, [] == "") // true
print(#"["1", "2"] == "1,2" => "#, ["1", "2"] == "1,2") // true
print(#""" === 0 => "#, "" === 0) // false
print(#""0" === 0 => "#, "0" === 0) // false
print(#"false === "0" => "#, false === "0") // false
@helje5
Copy link
Author

helje5 commented Jun 17, 2025

Output

""    == 0          =>  true
"0"   == 0          =>  true
0     == "0"        =>  true
false == "0"        =>  true
false == []         =>  true
[]    == ![]        =>  true
[1]   == 1          =>  true
[]    == []         =>  false
[]    == ""         =>  true
["1", "2"] == "1,2" =>  true
""    === 0         =>  false
"0"   === 0         =>  false
false === "0"       =>  false

Rules:

  1. Same Type → Compare Directly
  2. null == undefined → true
  3. Number == String → Convert String to Number
  4. Boolean == Any → Convert Boolean to Number
  5. Object == Primitive → Convert Object to Primitive
  6. String/Number == Object → Convert Object to Primitive, then Coerce

@helje5
Copy link
Author

helje5 commented Jun 17, 2025

(The implementation it is not entirely complete)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment