Is there a way to automatically determine the type of the 'res' in resHandler?
Unfortunately, you cannot do that.
In Typescript, the type of a value is not determined based on how it is used.
Instead, Typescript verifies if the usage of a value aligns with how its type was declared.
Consider this scenario:
sendRequest<PersonType>(resHandler)
const someResponse: SomeOtherType = getJson('...')
resHandler(someResponse) // What should be the type of the argument here?
Would you expect the type of the resHandler
argument to change to res: PersonType | SomeOtherType
? Typescript does not make that change.
Typescript first looks at this:
function resHandler(res){
console.log(res)
}
If no type is provided for res
, Typescript infers it as any
(which could be an issue if noImplicitAny
is enabled).
Then it checks to ensure that everywhere the resHandler
function is used is compatible with its interface.
To avoid manually typing the res
parameter, you can inline the function like this:
sendRequest<PersonType>((res) => console.log(res.name)) // valid
In this case, the usage is tied to the declaration because the function is created within the context of T extends PersonType
, so Typescript knows that typeof res extends PersonType
.
Alternatively, you can manually type the argument if you want direct interaction with PersonType
.
function resHandlerForPerson(res: PersonType){
console.log(res.name)
}
sendRequest<PersonType>(resHandlerForPerson) // valid
sendRequest<{ someOtherType: string }>(resHandlerForPerson) // type error
Now you have a resHandlerForPerson
function specifically for PersonType
, which will result in a type error if used with any other type.
See Playground