Depends on use case. Here several ways. https://typescriptlang.org/play/...
Somehow we imported
type fInterface = (...params: fArgs) => fRet
type fArgs = [number, string]
type fRet = boolean
No matter - they are interchangeable with Parameters and ReturnType
And we have function implemented wrong
function nop() {}
- Manually pick parameters type
function isEqual0(x: fArgs[0], y: fArgs[1]): fRet {
//return x == y //TS-ERROR: This condition will always return 'false' since the types 'number' and 'string' have no overlap.ts(2367)
return `${x}` == y
}
- With destructing
function isEqual1(...args: fArgs): fRet {
const [x, y] = args
return `${x}` == y
}
- With overload. Strict usage but during implementation all parameters are
any.
function isEqual2(...args: Parameters<fInterface>): ReturnType<fInterface>
function isEqual2(x: any, y: any) {
return x == y
}
- After all we can validate by re-typing (like typing-the-function). Also there will be type validation in parent module in any case.
function isEqual3(x: any, y: any) {
const valid: typeof isEqual3 extends fInterface ? true : never = true
if (!valid)
throw Error()
return x == y
}
const _exports = {
isEqual0, isEqual1, isEqual2, isEqual3, nop
}
, _exportCheck = _exports as Record<keyof typeof _exports, fInterface> //TS-ERROR The types returned by 'nop(...)' are incompatible between these types.
module.exports = _exportCheck
export default _exportCheck
export {
isEqual0, isEqual1, isEqual2, nop
}
So many ways to achieve TS-Error if something was wrong.