The main points of this answer are that,first, it seems rather difficult to have a fully universal mechanism for option-validation, and second, such a mechanism is not currently available in Mathematica on the language level (meaning automation of complete option-checking, including both the option's name and value).
In the particular case in question,
Import does not have options, but the strict option-checking via
OptionPattern probably wasn't employed because
Import has a rich syntax and may have arguments containing rules that look like options (while they aren't). Generally,
OptionsPattern were introduced in V6, so I am sure that there is a lot of internal code that still uses
OptionQ instead (which IMO is perfectly fine as long as option names, values, etc are checked by other means). Also, it may not always be advantageous to use the newer constructs.
Let's also keep in mind that even
OptionValue don't give you full option-checking, since these constructs don't check the value of a passed option, only its name. So, in practice, checking the validity of a given passed option is still a necessity for production-quality code, even if the newer constructs are used. I am not aware of any further system-wide automation for this (which may be just my ignorance), so it looks like this is dealt with on a case-by-case basis.
Philosophically, I think that the original design, using the semantics of rules and pattern-matching to have options (optional named arguments) in the language without introducing any additional constructs, was quite neat. Later, it probably became clear that options and their checking represent a special case, common enough that the introduction of some additional (rather magical) constructs to handle them specially could be justified. It may be, that at some point some additional constructs will be introduced to automate validating the values of options (or may be not). But, there is always a tradeoff between the purity of the language design, and safety/automation: from the viewpoint of pure semantics of options, the newer
OptionsPattern constructs weren't really needed, rules + pattern-matching were enough.
While we are at it, let me mention (shameless plug) that I made my own attempt to automate the option-validating process by means of packages which I wrote and named CheckOptions and PackageOptionChecks and which live here. The former basically parses the definition(s) of a particular function and generates new definitions which validate the options according to some declarative specifications. The latter brings the functionality of the former to entire packages, and adds some convenient declarative syntax to specify how options are to be validated. Both can be used to "protect" options for functions you write yourself, as well as for functions/packages written by someone else. The latter package can be used to protect options of functions in some other package without modifying the source code of that other package.
I would hesitate to recommend using these packages in production, unless you inspect exactly how they modify the original functions' definitions (or are otherwise sure that they won't break anything), since they are rather intrusive in the way they work, but I found them quite helpful for debugging. For your own packages, where you control and understand the code, however, I would consider using them as an option (if you are concerned about option-checking), particularly if your code does not use some meta-programming tricks such as run-time generation of functions' definitions. One practical example of their use is the package PackageSymbolsDependencies, which lives at the same page.