First of all, you don't want [Key in keyof V] because V is a some string-like type; keyof V will be something like "length" | "substring" | ..., all the keys with which you can index into a string. You just want to iterate over the union members of V themselves, like [K in V].
Then when you wrote V extends string ? ... : you were accidentally making a distributive conditional type, which would result in { CLUSTER_DATA_PLATFORM: string } | { SOTTOCLUSTER_DATA_PLATFORM: string } instead of the desired result. You can fix that by wrapping the check in a one-tuple like [V] extends [string] ? ... :. That gives you this:
type FromValues<T> = T extends Record<infer K, infer V>
? [V] extends [string] ? { [Key in V]: string } : never
: never
which works:
type Z = FromValues<typeof mapping>;
/* type Z = {
CLUSTER_DATA_PLATFORM: string;
SOTTOCLUSTER_DATA_PLATFORM: string;
} */
But you could simplify to avoid conditional types entirely:
type FromValues<T extends Record<keyof T, string>> =
{ [K in T[keyof T]]: string };
which gives the same result.
Obviously there are edge cases, if you try to pass types to FromValues where some of the value types are not strings, you'll get different behaviors, and you have to figure out what the desired behavior should be and implement something that works that way. That's out of scope of the question as asked, though.
Playground link to code