Is it possible to query posts with tax queries after multisite switch_to_blog() function?

Yes, it is possible, but you will need to register the taxonomy on both sites because switch_to_blog() does not register the taxonomy for you, it mainly only switches the database and yet, taxonomies are not stored in the database, only the terms in the taxonomies.

But you don’t have to register the taxonomy on page load.. (but yes, that’s the proper way to do it). Because as long as it is registered, then the tax_query will work. And here’s an example to register the supplier-type taxonomy right after you call switch_to_blog():

// switch to purchase blog
switch_to_blog($site_purchase);

// Register the taxonomy.
$taxonomy = 'supplier-type';
if ( ! taxonomy_exists( $taxonomy ) ) {
    register_taxonomy( $taxonomy, null, [] );
    // or call your custom function which registers the taxonomy using the proper args
}

// ... your code.

[Edit] I gave the above example because (in the comments) you said, “using conditional logic to check if site is site and then registering types/taxes” and also “the tax is only registered on the purchase site, not the data site“. So the above should work even if you conditionally registered the taxonomy.

Also, in response to “Querying custom post types might not actually require register_post_type to be envoked, but tax_queries might actually need to understand the taxonomy is registered“, yes that’s correct.

More specifically, the tax query class uses taxonomy_exists() when generating the SQL statement (JOIN and WHERE clauses) for the tax query’s clauses (see source on Trac), and when the specified taxonomy is not registered, then the WHERE clause will be 0 = 1 (as in WHERE 1=1 AND ( 0 = 1 ) AND tsp_2_posts.post_type="purchase-supplier" ...) just as you could see in the $suppliers->request value here. Hence, that explains the empty posts array or the “why tax_query is failing in the switch_to_blog() function“.

So make sure the taxonomies used in your tax queries are properly registered. And despite WP_Query doesn’t check if a post type exists (e.g. using post_type_exists()) when querying for posts in custom post types, if after switching to any site you need to get the post type object or data (e.g. using get_post_type_object()), then make sure the post type is registered correctly.