This question is similar to this one, but I think it lacks a lot of the main caveats and concerns raising issues there because I'm not making any assumptions that the properties of a given interface are a closed or ordered set.
Suppose I have an interface and couple of functions like this:
interface Person {
givenNames: string,
familyNames: string,
charactersToDisplayNames: number,
age: number,
weight: number,
fastest5KTime: number,
//... could be plenty of others
}
function writeFields<
T extends object,
F extends (keyof T)[]
>(
dest : T,
fieldsToWrite : F,
valuesToWrite : WhatTypeGoesHere<T, F>, //Can be defined above
) {/*...*/}
function setNames(dest: Person, givenNames: string, familyNames: string) {
writeFields(
dest,
['givenNames', 'familyNames', 'charactersToDisplayNames'],
//In this case, the 3rd param should be
//a tuple of type [string, string, number]
[givenNames, familyNames, givenNames.length + 1 + familyNames.length]
)
}
//other functions set other fields, or do so with parameters, etc...
//the desire is to avoid any non-type refactoring esp. to writeFields().
How should the type noted above as WhatTypeGoesHere
be defined so that the third parameter has proper type-checking?