I need the function that allow pass only keys if the value in object has string type:
type GetNames<FromType, KeepType = any, Include = true> = {
[K in keyof FromType]:
FromType[K] extends KeepType ?
Include extends true ? K :
never : Include extends true ?
never : K
}[keyof FromType];
const functionOnlyForStrings = <T>(obj: T, key: GetNames<T, string>) => {
const t = obj[key]
// do something with strings
return t.toUpperCase()
}
const testObj: {a: string, b: number} = {a: 'test', b: 123}
const test = functionOnlyForStrings(testObj, 'a')
const wrongParam = functionOnlyForStrings(testObj, 'b')
In lines:
const test = functionOnlyForStrings(testObj, 'a')
const wrongParam = functionOnlyForStrings(testObj, 'b') // here I get an error message
Everything works great. If I pass b key than TS shows me an error.
But problem in function functionOnlyForStrings. Inside this function TS doesn't know that obj[key] is always string. And show me the error:
Property 'toUpperCase' does not exist on type 'T[{ [K in keyof T]: T[K] extends string ? K : never; }[keyof T]]'.
{ [index:string] : string }.functionOnlyForStringsisstrings, but it is alway string. How should I describe it for TS?