tflint is doing right now is totally unsupported:
hashicorp/terraform is an executable program, not a library. While some of the packages are (for historical reasons) technically importable, please note that the versioning scheme of the repository relates to compatibility with Terraform as used through the CLI interface, and not to the internal Go package APIs. Your codebase is very likely to be broken by future changes to Terraform.
With all of that said, I think the above is also in a way the answer to your question: linters tend to differentiate things that a main language parser does not, and in order to do that they need to work at a lower level of abstraction than the main language implementation. In your case, I think that would be using the HCL library directly, and decoding the HCL data structure in whatever way gets you the details you need to implement the linter rules you want to implement.
For the specific problem you’re talking about for example, you could use the HCL API to decode the contents of the
variable block itself (rather than Terraform’s higher-level representation of it) and then check whether there is an element called
type in the map of attributes in that body. By dropping down one level of abstraction you can distinguish presence vs. absence in a way that Terraform’s application-level models do not.