typescript - 为什么此代码片段允许 Typescript 从 "parent"函数推断泛型?

标签 typescript

似乎有一个未记录的功能,它允许函数从作为参数传递的函数中推断出类型。

我试图理解为什么会这样,以及它是否是有意为之。

Playground

给定一个 Model,然后使用通用的 updateapply 函数,我可以从 apply 推断出类型> 当使用 update 的结果作为参数时,使用技巧 T extends infer U ? U:从不:

interface Model {
    foo: number
    bar: string
}

function apply<T>(fn: (t: T) => T) {};

function whyDoesThisWork() {

    function update<T>(u: T extends infer U ? Partial<U> : never) { return (t: T) => ({ ...t, ...u }) };

    // Somehow, Typescript is able to infer that we want Model to be the generic supplied for update
    apply<Model>(update({ foo: 1 }));

}

function thisDoesntWorkForObviousReasons() {

    function update<T>(u: Partial<T>) { return (t: T) => ({ ...t, ...u }) }

    // update infers T as { foo: 1 }, because that makes sense
    apply<Model>(update({ foo: 1 }));

}

最佳答案

出现此行为的原因是 Contextual Typing .

可以将“技巧”提取到名为 DontInfer 的帮助程序中:

type DontInfer<T> = T extends infer S ? S : never;

何时 DontInfer用于通用函数签名, T不会推断它在哪里使用。在我的示例中,通用参数 u可以说是形状Partial<T> ,但是T u 不会推断出:

function update<T>(u: DontInfer<Partial<T>>) { return (t: T) => ({ ...t, ...(u as Partial<T>) }) };

这意味着update函数将无法推断 T如果单独使用:

// T is inferred to be `unknown`
update({ foo: 1 })

但是当在上下文中使用时,T 可以被推断出来:

// T is inferred to be Model
setState<Model>(update({ foo: 1 }));

DontInfer适用于此目的,因为它 defers evaluating unresolved conditional types .

关于typescript - 为什么此代码片段允许 Typescript 从 "parent"函数推断泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70120188/

相关文章:

node.js - TypeORM全局创建连接

Typescript - 通过字符串索引查找枚举

typescript 抽象类静态方法未强制执行

Angular :错误 TS2322:类型 'ItemsResponse' 不可分配给类型 'string[]'

node.js - Nestjs:如何使用nest/cli 从nestjs monorepo 中删除特定应用程序

typescript - 如何使用 TypeScript mixins 避免 "unresolved function"错误?

c# - 如何在 Typescript 中模仿 C# 项目结构?

typescript - 如何在 TypeScript 中使用元数据键入表格数据?

typescript - TextDocumentContentProvider HTML/JScontent 可以与扩展代码对话吗?

typescript - 如何在 Typescript React 中遍历组件的子组件?