iOS: Union with literal numbers will fail on build
What's happening?
Consider the following type:
type ColumnCount = 'auto' | '1' | '2'
Nitro generates the following Swift file:
///
/// ColumnCount.swift
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2025 Marc Rousavy @ Margelo
///
/**
* Represents the JS union `ColumnCount`, backed by a C++ enum.
*/
public typealias ColumnCount = margelo.nitro.nitroreadium.ColumnCount
public extension ColumnCount {
/**
* Get a ColumnCount for the given String value, or
* return `nil` if the given value was invalid/unknown.
*/
init?(fromString string: String) {
switch string {
case "auto":
self = .auto
case "1":
self = .1
case "2":
self = .2
default:
return nil
}
}
/**
* Get the String value this ColumnCount represents.
*/
var stringValue: String {
switch self {
case .auto:
return "auto"
case .1:
return "1"
case .2:
return "2"
}
}
}
Reproduceable Code
type ColumnCount = 'auto' | '1' | '2'
Relevant log output
This will cause the following error on build.
# ERROR
error '.1' is not a valid floating point literal; it must be written '0.1'
error '.2' is not a valid floating point literal; it must be written '0.2'
error cannot assign value of type 'Double' to type 'margelo.nitro.nitroreadium.ColumnCount'
error expression pattern of type 'Double' cannot match values of type 'margelo.nitro.nitroreadium.ColumnCount'
Device
iPhone 16 Emulator
Nitro Modules Version
0.25.2
Nitrogen Version
0.25.2
Can you reproduce this issue in the Nitro Example app here?
I didn't try (⚠️ your issue might get ignored & closed if you don't try this)
Additional information
- [ ] I am using Expo
- [x] I am using Nitrogen (nitro-codegen)
- [x] I have read and followed the Troubleshooting Guide.
- [ ] I created a reproduction PR to reproduce this issue here in the nitro repo. (See Contributing for more information)
- [x] I searched for similar issues in this repository and found none.
What? How does it go from one/two to 1/2?
Sorry, I forgot to change from 'two' back to '2' after my fix... 😅
Ah okay that makes sense. Well I guess this is a weird edge case, not sure if I even want to support that.
If you're not willing to support that, then we could throw a codegen error if the type can be parsed as a number, since the generated code compiles on Android but not iOS.
How does the generated Kotlin/C++ code look like for Android then? Are you sure that works? Wouldn't it also just use 1 as a property name?
So I thought a bit about this and I think this would be too complex to really support. There are tons of cases where you can use wrong names, like e.g.;
type SchoolThing = 'class' | 'room'
class will fail to build since it's obviously a reserved keyword in C++, Swift, Kotlin and even JS. Do I have to support that as well?
I feel like it would be cool to have an error thrown for this, but it's just adding code complexity and I'll never cover all cases.
type InvalidThings = ';' | '1' | ' ' | 'struct' | 'enum' | '+' | '....'