如何在代码块外部引用TypeScript块内定义的类型?含Drizzle场景
如何在函数外部引用块内定义的类型
我在函数内部通过typeof生成了一个类型(比如Drizzle ORM查询返回值的类型),想在外部函数里使用这个类型,但受限于作用域无法直接引用。
Drizzle ORM场景示例
function a() { const emisor = db.query.registro.findFirst({ where: eq(registro.nrc, '1234'), with: { actividad: true, municipio: true } }); type Emisor = typeof emisor; processDTE(emisor); }; function processDTE(emisor){ // 此处希望给emisor标注Emisor类型,但无法引用该类型 }
理想写法是function processDTE(emisor: Emisor),但Emisor是函数a内部定义的类型,外部无法访问。
最小复现代码
function start() { const variable = { a: 'Some object with a complex structure....' }; type myType = typeof variable; process(variable); } function process(variable: myType) { variable.a = 'Something'; }
这段代码中process函数的myType会报错,因为myType仅在start函数内部有定义。
解决方法
通用TypeScript方案
把类型定义提升到函数外部的模块/全局作用域,或通过工具类型从现有值/函数中提取:
- 提前提取类型到外部
如果能直接获取目标值的类型来源(比如Drizzle的查询方法),直接在外部定义类型:
// 外部定义类型 type Emisor = Awaited<ReturnType<typeof db.query.registro.findFirst>>; function a() { const emisor = db.query.registro.findFirst({ where: eq(registro.nrc, '1234'), with: { actividad: true, municipio: true } }); processDTE(emisor); }; function processDTE(emisor: Emisor){ // 正常使用类型 }
- 用工具类型从函数返回值提取
如果目标变量是某个函数的返回值,用ReturnType+Awaited(异步场景)提取类型:
// 封装查询逻辑(可选,也可直接用原查询方法) function getEmisor() { return db.query.registro.findFirst({ where: eq(registro.nrc, '1234'), with: { actividad: true, municipio: true } }); } // 提取返回值类型 type Emisor = Awaited<ReturnType<typeof getEmisor>>; function processDTE(emisor: Emisor){ // 正常使用类型 } function a() { const emisor = getEmisor(); processDTE(emisor); };
Drizzle专属方案
Drizzle ORM提供了内置类型工具,可直接从Schema生成关联查询的类型:
import { InferSelectModel } from 'drizzle-orm'; import { registro, actividad, municipio } from './your-schema'; // 生成包含关联表的完整查询类型 type Emisor = InferSelectModel<typeof registro> & { actividad: InferSelectModel<typeof actividad>; municipio: InferSelectModel<typeof municipio>; }; function a() { const emisor = db.query.registro.findFirst({ where: eq(registro.nrc, '1234'), with: { actividad: true, municipio: true } }); processDTE(emisor); }; function processDTE(emisor: Emisor){ // 正常使用类型 }
内容的提问来源于stack exchange,提问作者Ben Quan
相关产品推荐
相关产品推荐

