Mapped types https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#mapping-modifiers seems to be what you are looking for.
I was able to chieve this.
type TPerson = {
name: string;
age: number;
}
type TIn = {
xa: number;
xb: string;
xc: boolean;
// ...
}
type TRename = {
ya: "xa";
yb: "xb";
yc: "xc";
// ...
}
type TOut = {
ya: number;
yb: string;
yc: TPerson;
// ...
}
function fn<T extends { [K in keyof TIn]?: TIn[K] }>(input: T): {
[K in keyof TOut]: T[TRename[K]] extends TIn[TRename[K]] ?
TOut[K] :
undefined
} {
return;
}
var test0 = fn({ xa: 77 }); // intelisense type hint:
//var test0: {
// ya: number;
// yb: undefined;
// yc: undefined;
//}
var test1 = fn({ xc: false }); // intelisense type hint:
//var testl: {
// ya: undefined;
// yb: undefined;
// yc: TPerson;
//}
var test2 = fn({ xa: 0, xb: "", xc: true }); // intelisense type hint:
//var test2: {
// ya: number;
// yb: string;
// yc: TPerson;
//}