You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在代码块外部引用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方案

把类型定义提升到函数外部的模块/全局作用域,或通过工具类型从现有值/函数中提取:

  1. 提前提取类型到外部
    如果能直接获取目标值的类型来源(比如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){
   // 正常使用类型
}
  1. 用工具类型从函数返回值提取
    如果目标变量是某个函数的返回值,用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:43:17