Is this valid?
Yes; a constexpr pointer object is allowed to contain the address of any object of static storage duration.
Code compiles only starting from C++17.
Prior to C++17, static constexpr data members require an out-of-class definition as well:
template <class Derived>
constexpr const component_type_data component<Derived>::type_data;
template <class Derived>
constexpr const component_type_data* component<Derived>::component_type;
If this valid, how compiler can know address beforehand?
If you mean the numerical address: the answer is that the compiler cannot, in general, know that, as it may not be assigned until link time or possibly even until the program is loaded by the operating system.
However, the reason why addresses can be used as constant expressions is that the compiler effectively represents them symbolically, i.e., "address of component<int>::type_data". If you were to then dereference such a pointer at compile time, the compiler would know that the result is "lvalue referring to component<int>::type_data". So compile-time computation in C++ is really quite complicated and involves a lot of metadata (in the post-C++17 world, we really expect a lot from our compilers). Note that once you attempt to examine the numerical address (i.e., using reinterpret_cast) you no longer have something that is usable at compile time.