如何在TypeScript中根据函数类型执行对应逻辑?
解决方案
TypeScript的类型别名在编译后会被完全擦除,运行时无法直接通过typeof判断A或B这类自定义类型。要实现对这两个函数类型的分支判断,得借助运行时可检测的特征结合TypeScript的类型收窄能力。
具体实现
你的两个函数类型A和B的参数个数不同(A接收1个参数,B接收2个参数),可以利用函数的length属性(返回函数形参个数)来区分,再通过类型谓词或类型断言让TypeScript识别分支内的具体类型:
方式1:使用类型谓函数(推荐)
type A = (a: number) => Promise<string> type B = (b1: number, b2: string) => number | undefined // 定义类型谓函数,帮助TS收窄类型 function isA(fn: unknown): fn is A { return typeof fn === 'function' && fn.length === 1; } function isB(fn: unknown): fn is B { return typeof fn === 'function' && fn.length === 2; } function test(arg: A | B) { if (isA(arg)) { // 此处arg被TS识别为A类型 arg(123).then(str => console.log(str)); } else if (isB(arg)) { // 此处arg被TS识别为B类型 const result = arg(123, 'test'); console.log(result); } }
方式2:直接在条件中收窄类型
如果不需要复用判断逻辑,也可以直接在分支条件里写检测逻辑,配合类型断言:
type A = (a: number) => Promise<string> type B = (b1: number, b2: string) => number | undefined function test(arg: A | B) { if (typeof arg === 'function' && arg.length === 1) { const aFn = arg as A; aFn(123).then(s => console.log(s)); } else if (typeof arg === 'function' && arg.length === 2) { const bFn = arg as B; const res = bFn(456, 'hello'); console.log(res); } }
补充说明
如果你的函数类型参数个数相同,就得给函数添加运行时唯一标识来区分,比如给函数添加自定义属性:
type A = ((a: number) => Promise<string>) & { type: 'A' } type B = ((b1: number, b2: string) => number | undefined) & { type: 'B' } // 使用时需要给函数添加标识 const fnA: A = Object.assign((a: number) => Promise.resolve(a.toString()), { type: 'A' }); const fnB: B = Object.assign((b1, b2) => b1, { type: 'B' }); function test(arg: A | B) { if (arg.type === 'A') { arg(123).then(console.log); } else { console.log(arg(456, 'test')); } }
内容的提问来源于stack exchange,提问作者Hostek
相关产品推荐
相关产品推荐

