Of course you can infer!
Typescript has the most powerful generic system ever seen!
It just takes some mystic syntax.
You may write that (check it on Typescript Playground) :
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg: IEngineClas["viewer"] extends (arg: infer U) => any ? U : any) {
return true
}
}
let test = (new MyClass()).viewer("hop") // Type OK
let test2 = (new MyClass()).viewer(1) // Wrong type
Explanation:
IEngineClas["viewer"] can retrieve the type of your parent function: (arg:string) => boolean
Using the conditional types, you can retrieve the arg you want by using the infer keyword to assign it to a generic.
Read it like this: if the type of IEngineClas["viewer"] is (arg: U) => any (a function with an argument), grab the type of U (the first argument) and use it as the type of the parameter arg. Otherwise, use the type any.
Edit
A better way to write it, with a type (check it on Typescript Playground):
type firstArg<T> = T extends (arg: infer U) => any ? U : any
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg: firstArg<IEngineClas["viewer"]>) {
return true
}
}
let test = (new MyClass()).viewer("hop") // Type OK
let test2 = (new MyClass()).viewer(1) // Wrong type
The reason
On a different case, I asked one day why these expected inference behaviors concerning the abstract classes weren't the default, and was answered it was due to performance issues. And I admit that on big projects, Typescript becomes excessively slow. Even if a compilation flag to activate the typings or not on the abstract classes would have been welcomed.
The post where I asked: https://github.com/Microsoft/TypeScript/issues/21428
Ah, and...
If you just want to get rid of the implicit any warning, just specify the any type explicitly: viewer(arg:any), or disable the noImplicitAny flag in your compiler options.