繁体   English   中英

如何使 TS 在映射类型上自动推断类型 arguments?

[英]How to make TS automatically infer type arguments on mapped types?

考虑以下代码( Playground ):

type Either<E, D> = ["error", E] | ["data", D]

type GenericTuple<T = any> = [T, ...T[]];

// [Either<E, D1>, Either<E, D2>, ...] -> Either<E, [D1, D2, ...]>
declare function mergeEithers<E, Ds extends GenericTuple>(
    eithers: { [K in keyof Ds]: Either<E, Ds[K]> }
): Either<E, Ds>;

type MessageError = {message: string};
declare const either1: Either<MessageError, string>
declare const either2: Either<MessageError, number>

// unpacked: Either<unknown, [string, number]>
const unpacked = mergeEithers([either1, either2])

我们应该如何编写它以便 TS 自动推断unpackedEither<MessageError, [string, number]>

您正在尝试在mergeEithers的类型签名中使用映射类型的推断。 我发现在这种情况下编译器并不总是能够提取所需数量的信息。 您正在传入一个类型为 { [K in eithers { [K in keyof Ds]: Either<E, Ds[K]> }的值,并希望编译器可以从中推断出EDs 一般来说,它可以用Ds做一些合理的事情(因为它是同态映射)并且可能在你得到任何对E有用的东西之前就放弃了。

在这种“向后”推断不可靠的情况下,我通常使用 go 进行蛮力“向前”推断:如果我希望编译器推断类型A ,我应该传入A类型的值。 为此,我们将选择eithers类型A这往往会被正确推断。 然后我们将使用A计算所需的 output 类型,该类型以前称为Either<E, Ds>

declare function mergeEithers<A extends GenericTuple<Either<any, any>>>(
    eithers: A
): Either<
    Extract<A[number], ["error", any]>[1],
    { [K in keyof A]: Extract<A[K], ["data", any]>[1] }
>;

在这里,我使用Extract实用程序类型来提取错误和联合的数据部分。 类型Extract<A[number], ["error", any]>[1]应该是eithers元组的所有可能不同的错误类型的并集,而类型Extract<A[K], ["data", any]>[1]应该是eithers元组的每个元素K的数据类型。

让我们看看它是否有效:

const unpacked = mergeEithers([either1, either2])
// const unpacked: Either<MessageError, [string, number]>

看起来不错。

Playground 代码链接

暂无
暂无

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

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