如何让TypeScript函数返回类型依赖于输入参数?
解决TypeScript泛型条件类型的返回值自动推导问题
你需要让md2docx函数根据传入的encoding参数,自动返回对应类型的值,并且调用时无需手动判断就能获得正确的类型推导。原代码的写法无法实现这一点,核心原因是TypeScript无法将函数内部的返回值与泛型参数的具体值建立关联。
方案1:使用函数重载(推荐)
函数重载能明确每种输入参数组合对应的返回类型,让TypeScript直接根据传入的encoding推导出返回值类型,代码更清晰且无需额外断言:
export type Encoding = 'buffer' | 'blob' | 'base64' // 定义三种参数组合对应的重载签名 export default async function md2docx(text: string, encoding: 'buffer'): Promise<number>; export default async function md2docx(text: string, encoding: 'blob'): Promise<Blob>; export default async function md2docx(text: string, encoding: 'base64'): Promise<string>; // 函数实现(需覆盖所有可能的返回类型) export default async function md2docx( text: string, encoding: Encoding, ): Promise<number | Blob | string> { switch (encoding) { case 'buffer': return 10; // 实际替换为Buffer.from(text) case 'blob': return new Blob([text]); case 'base64': return btoa(text); // 原代码用atob是解码逻辑,这里返回base64字符串改用btoa更合理 } } // 调用时自动推导output为Blob类型,直接调用方法即可 md2docx('foo', 'blob').then(output => { output.arrayBuffer(); });
方案2:使用映射类型+泛型
通过定义编码到返回类型的映射关系,结合泛型实现类型推导,适合编码类型较多的场景,但需要类型断言消除报错:
export type Encoding = 'buffer' | 'blob' | 'base64'; // 建立编码与返回类型的映射 type EncodingReturnType = { buffer: number; // 实际项目中替换为Buffer类型 blob: Blob; base64: string; }; export default async function md2docx<E extends Encoding>( text: string, encoding: E, ): Promise<EncodingReturnType[E]> { switch (encoding) { case 'buffer': return 10 as EncodingReturnType[E]; case 'blob': return new Blob([text]) as EncodingReturnType[E]; case 'base64': return btoa(text) as EncodingReturnType[E]; } } // 同样能自动推导output为Blob类型 md2docx('foo', 'blob').then(output => { output.arrayBuffer(); });
原代码问题解析
原代码中虽然用了条件类型E extends 'blob' ? Blob : E extends 'buffer' ? number : string,但TypeScript在函数内部无法验证返回值是否符合该条件类型——因为泛型E在函数内部是未具体化的类型参数,无法和每个case的具体返回值关联,导致类型报错;同时调用时也无法正确推导返回值类型,必须手动判断。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

