It’s generally waaaay easier to ensure invariants through constructor methods than type parameter constraints. Yes, it’s not “statically enforced” but neither is Julia itself.
struct MyType{D, G}
data::D
grid::G
end
function MyType(data, grid)
eltype(data) === eltype(grid) || throw(ArgumentError("blah"))
# more checks as necessary
return MyType{typeof(data), typeof(grid)}(data, grid)
end