繁体   English   中英

为什么此代码段允许 Typescript 从“父”function 推断出泛型?

[英]Why does this snippet allow Typescript to infer a generic from a "parent" function?

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

我试图了解为什么会这样,以及是否是故意的。

操场

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

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签名中使用 DontInfer 时,不会推断T的使用位置。 在我的示例中,可以说通用参数u的形状为Partial<T> ,但T不会由u推断:

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

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

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

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

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

DontInfer用于此目的是因为它推迟评估未解决的条件类型

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM