试图理解“T 扩展推断 U”的限制

And*_*sta 9 typescript conditional-types

我已经理解了这样的事情:

type GenericExample<T> = T extends (infer U) ? U : 'bar';
Run Code Online (Sandbox Code Playgroud)

等于:

type GenericExample<T> = T extends T ? T : 'bar';
Run Code Online (Sandbox Code Playgroud)

但是当事情变得更加复杂时,TypeScript 会抱怨:

type Types = 'text' | 'date' | 'articles' | 'params';

type MyExperiment<Type extends Types> =  { t : Type };

type MyExperimentsUnion = Types extends (infer U) ? MyExperiment<U> : never;
// Type 'U' does not satisfy the constraint 'Types'.
// Type 'U' is not assignable to type '"params"'.
Run Code Online (Sandbox Code Playgroud)

所以我想问一下为什么这是错误的:在这种特殊情况下应该发生联合分布,所以推断的U类型应该是text,然后date等等。那么,T extends (infer U)真正的意思是什么,什么时候使用它是合适的?

zhu*_*ber 3

我不认为它应该按照您使用它的方式使用 - 基本上infer应该用于“推断”(或解决可能更好的命名?)类型,最常见的是泛型。

您使用它的方式,您正在创建一个没有任何“动态”部分的类型(基本上它不是通用的),这意味着它总是相同的,因此从总是相同的东西推断是没有意义的。因为在编译时您已经知道Typesextends only Types & '...anything else',并且由于您无法在MyExperimentsUnion类型中定义其他部分,infer所以没有太大用处。

用法示例

interface Action<T> {
    payload: T
}

type ExtractGeneric<T> = T extends Action<infer X> ? X : never

function getPayload<T extends Action<any>>(action: T): ExtractGeneric<T> {
    return action.payload;
}

const myAction = { payload: 'Test' };
const myPayloadWithResolvedType = getPayload(myAction);
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,myPayloadWithResolvedType将具有string解析类型,因为如果您没有使用infer,则必须将该返回类型作为第二个参数传递,可能如下所示:

function getPayloadNonExtract<T extends Action<U>, U>(action: T): U {
    return action.payload;
}
Run Code Online (Sandbox Code Playgroud)

是游乐场的链接。

干杯。

  • 我想我理解你的问题,但我不确定你希望打字稿如何解析“U”?`MyExperiment&lt;U&gt;` 应该是什么?我的意思是,“U”必须是“Types”的“子类”,但是打字稿无法确定“U”到底是什么,因为您没有传递任何类型(它不是泛型类型),而且我不明白为什么它应该默认为“类型”。我想这就是您收到错误的原因之一,尽管我同意它可以更具描述性,但似乎他们的心态是开发人员应该知道“infer”不应该以这种方式使用。 (2认同)