解析 TypeScript 类型中的 Promise

2024-05-27

这是一个延续关于解决返回类型的问题 https://stackoverflow.com/questions/53174191/infering-return-type-in-a-nested-object-with-typescript. I'm so接近我想要做的事情(即有一个通用函数来基于经过验证的数据构建模型实例)并且它在 JS 中运行良好,但我无法弄清楚 TS 类型的最终部分。

关键是我的回报Init类型 - 特别是Builder<T[K]>部分。我明白为什么会导致Builder<(id: number) => Promise<Test>>作为返回的类型,但我一生都无法弄清楚如何告诉 TS 事实上它只是Test被返回,而不是返回 Promise 的函数Test.

可以将以下内容复制/粘贴到 VSCode(或其他)中以显示问题。这ter1变量应该是一个实例Test,当编译成 JS 时确实如此,但 TS 却看不到这一点。

export interface Builder<T> {
    (values: any, db: any): Promise<T>
}

export interface Wrapper {
    <T, TId>(
        construct: (id: TId, db: any | null) => Promise<T>,
        idSrc: string | string[],
        errorMsg: string
    ): Builder<T>
}

let builder: Wrapper = function (construct, idSrc, errorMsg ) {
    // A function that can be used to construct the instance
    return async function(values: any, db: any | null) {
        let id = null;
        let inst = await construct(id, db);

        if (!inst) {
            throw new Error(errorMsg);
        }

        return inst;
    };
}


class Test {
    is1 = true;

    static async fromId( id: number ) {
        var inst = new Test();
        // Some async action (e.g. a db read)
        return inst;
    }
}
class Test2 {
    is2 = true;

    static async fromId( id: number ) {
        var inst = new Test2();
        // Some async action (e.g. a db read)
        return inst;
    }
}


type Config<T extends {}> = {
    inputs?: {[index:string]: any},
    inst?: T;
};

type Init = <T extends {[key:string]: any}>(
    db: any,
    config: Config<T>
) => Promise<{[K in keyof T]: Builder<T[K]>}>; // ???

let init: Init = async function ( db, config ) {
    let ret: any = {};

    if ( config.inst ) {
        for (let [key, value] of Object.entries(config.inst)) {
            let res = await value( {}, {} );
            ret[ key ] = res;
        }
    }

    return ret;
}


async function allan () {
    let { ter1, ter2 } = await init( null, {
        inst: {
            ter1: Test.fromId,
            ter2: Test2.fromId
        }
    } );

    console.log( ter1.is1, ter1.is2 ); // should be `true undefined`

    // Test `builder` typing
    var t1Wrapper = builder( Test.fromId, 'id', 'test');
    var t2Wrapper = builder( Test2.fromId, 'id', 'test');

    var t1 = await t1Wrapper({}, {});
    var t2 = await t2Wrapper({}, {});

    t1.is1;
    t2.is2;
}

allan();

谢谢你!


看起来您想要的类型是这样的:

type Unpromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never;

type Init = <T extends { [key: string]: (...args: any[]) => Promise<any> }>(
  db: any,
  config: Config<T>
) => Promise<{ [K in keyof T]: Unpromise<ReturnType<T[K]>> }>; 

但我没有花时间检查你的所有代码来看看它是否有意义或者你是否正确地实现了它(这真的是一个吗?最小例子 https://stackoverflow.com/help/mcve?),所以如果您遇到其他问题,请原谅我。

说明:你的调用方式init()暗示T应该是一个对象,其属性是返回您关心的那种承诺的函数。 (我不确定这些函数的参数类型和数量是否重要)。所以对于每个属性T您想要提取其返回类型,然后提取承诺类型。

  • Unpromise<T> uses 条件类型中的类型推断 https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#type-inference-in-conditional-types提取承诺值的类型;所以Unpromise<Promise<XXX>>应该XXX.

  • ReturnType<T> is a 来自标准 TypeScript 库的类型 https://github.com/Microsoft/TypeScript/blob/v3.1.3/lib/lib.es5.d.ts#L1411-L1414它做了类似的事情来获取函数的返回类型;所以ReturnType<()=>XXX>应该XXX.

希望有帮助。祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解析 TypeScript 类型中的 Promise 的相关文章

随机推荐

  • 埃拉托斯特尼筛法是生成 1 到 N 素数的最佳算法吗?

    我在一次采访中被问到这个问题 我使用埃拉托色尼筛子概念和数组实现了一种算法 有没有更好的方法来解决这个问题 对于不知道筛子的人 请点击以下链接 http en wikipedia org wiki Sieve of Eratosthenes
  • VS Code:自定义关键字的注入语法范围在 C++ 中被覆盖

    我想制作一个小型 VS Code 扩展 为 C C 代码中的少数自定义关键字添加语法突出显示 我正在尝试通过注入语法来做到这一点source c and source cpp语言范围 遵循VS Code 语法高亮指南 https code
  • java.io.IOException:无法打开同步连接!进入 Nexus [重复]

    这个问题在这里已经有答案了 我尝试在 Eclipse 上运行我的应用程序 但发现了这些错误 这是第一次遇到 所以请给我关于这些错误的任何想法 我目前使用的是 Nexus 手机 2011 08 04 15 59 09 App Android
  • 如何在使用“document.createElement()”方法创建单元格后立即在 JavaScript 中设置单元格宽度?

    我已经使用 document createElement td 方法在 html 页面中为动态表格创建了单元格 现在希望用一些不同的值设置每个单元格的宽度 尝试过 cell width width 但它不起作用 我怎样才能实现它 Use s
  • 保护移动连接 - 存储秘密和密钥

    感谢您花时间阅读本文 我是一名年轻的开发人员 在 Web 项目和服务器端编码方面拥有一些专业经验 但我现在正在构建我的第一个移动应用程序 经过在线深入研究后 我还没有能够澄清我关于保护移动应用程序数据传输的一些问题 这是我认为我理解正确的
  • 给定一个正整数 n,如何打印高度为 n-1 的数字三角形?

    HackerRank 三角任务 https www hackerrank com challenges python quest 1 problem 仅使用算术运算 单个for loop 和一个单一的print陈述 不允许进行字符串操作 约
  • 需要帮助理解这段代码

    我正在尝试学习单元测试 我正在尝试对我在 asp net mvc 1 0 中制作的一些会员资格内容进行单元测试 我一直在关注一本关于 MVC 的书 我对一些东西感到困惑 希望有人能为我解答 我的框架使用 Nunit 和 Moq 问题一 pu
  • C# 从带引号的字符串中删除分隔符

    我正在编写一个程序 必须从文本文件中带引号的字符串中删除分隔符 例如 Hello my name is world 必须 Hello my name is world 起初这听起来很简单 我认为是这样 但是您需要检测引号何时开始 何时结束
  • do { ... } while (0) — 它有什么用? [复制]

    这个问题在这里已经有答案了 我已经看到这个表情十多年了 我一直在努力思考它有什么好处 因为我主要在 defines 中看到它 所以我认为它对于内部作用域变量声明和使用中断 而不是 gotos 很有用 对其他方面有好处吗 你用它吗 这是 C
  • 无捕获 lambda 是结构类型吗?

    P1907R1 http www open std org jtc1 sc22 wg21 docs papers 2019 p1907r1 html 接受 C 20 引入结构类型 它们是非类型模板参数的有效类型 GCC 和 Clang 都接
  • HTML DOM 宽度 + 可见窗口高度

    如何获取浏览器打开时可用空间的当前高度和宽度 我不需要整个文档的高度 只需要屏幕上可见的高度 你可以看看这个博客文章 http www howtocreate co uk tutorials javascript browserwindow
  • 找不到与给定名称匹配的资源:attr 'android:keyboardNavigationCluster'。更新到支持库 26.0.0 时

    我在更新到最新支持库版本 26 0 0 时遇到此问题 https developer android com topic libraries support library revisions html 26 0 0 https devel
  • 将 LUIS 与 FormFlow 集成

    我创建了一个机器人 里面有一个 FormFlow 现在 如果您输入 我想启动产品 LUIS 将告诉它必须转到哪个对话框 internal static IDialog
  • 倒计时:01:05

    如何在 Python 中创建一个看起来像 00 00 分钟和秒 的倒计时时钟 它独立成一行 每次减少一actual秒 则应将旧计时器替换为低一秒的新计时器 01 00变成00 59它实际上击中了00 00 这是我开始使用但想要改造的基本计时
  • Django 和 VirtualEnv 开发/部署最佳实践

    只是好奇人们如何结合 virtualenv 部署 Django 项目 更具体地说 如何使生产虚拟环境与开发计算机正确同步 我使用 git 进行 scm 但 git 存储库中没有 virtualenv 我应该这样做 还是最好使用 pip fr
  • Hibernate、MySQL 视图和 hibernate.hbm2ddl.auto = 验证

    我可以在 Hibernate 中使用 MySQL 视图 将它们视为表 即 该实体与为表创建的实体没有什么不同 但是 当 Hibernate 设置为验证模型时 我的应用程序将不会部署 因为它找不到视图 因为它假设它是一个表 是否可以在启用部署
  • PhpStorm:如何将部署设置从一个项目导出到另一个项目?

    我需要将部署设置从一个项目导出到另一个项目 我怎样才能做到这一点 我尝试导出所有设置 File gt Export Settings 并将它们导入到新项目中 但我在部署服务器列表中没有可用的配置 复制两者 idea deployment x
  • Firebase获取孩子ID swift ios

    我的 Firebase 看起来像这样 贝娄Active Orders看来childs根据他们的不同有不同的名字UID 用户身份 这是我的代码 用于获取孩子的 ID 无论孩子的名字是什么 但它似乎根本不起作用 获得的正确方法是什么child
  • 忽略 sed 查找和替换命令中的斜杠

    我正在尝试在终端中使用 sed 进行查找和替换 在 apache 配置文件中 我尝试替换 DocumentRoot var www with DocumentRoot var www mysite com public html 从命令行
  • 解析 TypeScript 类型中的 Promise

    这是一个延续关于解决返回类型的问题 https stackoverflow com questions 53174191 infering return type in a nested object with typescript I m