TypeScript中mssql多结果集IRecordSet的泛型类型如何正确设置
你当前的类型错误来自Data<T>的原始定义和实际返回结构不匹配:
原始type Data<T> = Array<IRecordSet<T>>代表所有结果集的行类型都是T,当你传入元组[BookData, CarData]作为T时,TypeScript会认为每一行的结果都是同时包含Book和Car的元组,和你「第一个结果集全是Book、第二个全是Car」的实际结构不符。
步骤1:调整Data泛型定义
我们需要把Data改成支持映射类型的版本,遍历你传入的类型元组,为每个位置生成对应行类型的IRecordSet:
import { IRecordSet } from 'mssql' // 支持多结果集不同类型的Data泛型 type Data<T extends any[]> = { [K in keyof T]: IRecordSet<T[K]> } async function getData (sql: string): Promise<Data<any[]>> { // 原有逻辑不变 return [] }
步骤2:正常标注业务类型
修改后原来的BooksAndCars定义就可以正常工作了:
interface BookData { name: string author: string } interface CarData { make: string model: string } // 传入元组类型,得到对应结构的结果集类型 type BooksAndCars = Data<[BookData, CarData]> async function getBooksAndCars (): Promise<void> { // 调用时做一次类型断言即可 const myData = await getData(` SELECT name, author FROM Books; SELECT make, model FROM Cars; `) as BooksAndCars const firstBook: BookData = myData[0][0] // 类型校验通过 const cars: CarData[] = myData[1] // 类型校验通过 }
可选优化:给getData加泛型支持
如果不想每次调用都手动写as断言,可以直接给getData加上泛型参数:
async function getData<T extends any[]>(sql: string): Promise<Data<T>> { // 原有逻辑不变,这里加个类型断言让TS不报错 return [] as unknown as Data<T> } // 调用时直接传入泛型即可,不需要额外写断言 async function getBooksAndCars (): Promise<void> { const myData = await getData<[BookData, CarData]>(` SELECT name, author FROM Books; SELECT make, model FROM Cars; `) const firstBook: BookData = myData[0][0] const cars: CarData[] = myData[1] }
内容的提问来源于stack exchange,提问作者Stephen Last
相关产品推荐
相关产品推荐

