gpt4 book ai didi

类型的 typescript 传播运算符

转载 作者:行者123 更新时间:2023-12-04 01:38:05 26 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Push type to the end of the tuple

(1 个回答)


2年前关闭。




我正在尝试定义一种类型,该类型将函数类型作为泛型参数并返回与输入函数类型相同的函数类型,只是它最后还有一个参数:

  type AugmentParam<F extends (...args: any[]) => any, ExtraParam> = F extends (
...args: infer Args
) => infer R
? (
...args: [
...Args,
ExtraParam
]
) => R
: never

使用示例:
type F = (x: number) => boolean
type F2 = AugmentParam<F, string> // (x: number, arg2: string) => boolean
...Args似乎不起作用,但是如果我将其更改为这样的东西,它会起作用:

  type AugmentParam<F extends (...args: any[]) => any, ExtraParam> = F extends (
...args: infer Args
) => infer R
? (
...args: [
Args[0],
Args[1] /* Spread doesn't work here, so it doesn't work for arbitrary number of arguments :( */,
ExtraParam
]
) => R
: never


但它只适用于特定数量的参数,我需要为每个 n 元函数定义一个这样的类型。

最佳答案

TypeScript 可以很容易地表示将类型附加到元组类型上,称为 Cons<H, T>像这样:

type Cons<H, T extends readonly any[]> =
((h: H, ...t: T) => void) extends ((...r: infer R) => void) ? R : never

type ConsTest = Cons<1, [2, 3, 4]>;
// type ConsTest = [1, 2, 3, 4]

您可以将此定义与条件映射元组类型一起使用来生成 Push<T, V>将类型附加到元组的末尾:
type Push<T extends readonly any[], V> = Cons<any, T> extends infer A ?
{ [K in keyof A]: K extends keyof T ? T[K] : V } : never

type PushTest = Push<[1, 2, 3], 4>;
// type PushTest = [1, 2, 3, 4]

但是 Push 的这个定义很脆弱。如果 T元组有 optional elements ,或者如果它来自函数的参数列表,您会注意到编译器将可选标记和参数名称“移动”到右侧一个元素:
type Hmm = (...args: Push<Parameters<(optStrParam?: string) => void>, number>) => void;
// type Hmm = (h: string | undefined, optStrParam?: number) => void

参数名称实际上并不是类型的一部分,因此虽然很烦人,但它不会影响实际类型。在可选参数之后附加一个参数......很奇怪,所以我不确定那里的正确行为是什么。不确定这些是否对您不利,但请注意。

无论如何你的 AugmentParam看起来像:
type AugmentParam<F extends (...args: any[]) => any, ExtraParam> =
(...args: Extract<Push<Parameters<F>, ExtraParam>, readonly any[]>)
=> ReturnType<F>

它有效(带有早期的警告):
type F = (x: number) => boolean

type F2 = AugmentParam<F, string>
// type F2 = (h: number, x: string) => boolean

type F3 = AugmentParam<F2, boolean>
// type F3 = (h: number, h: string, x: boolean) => boolean

好的,希望有帮助。祝你好运!

Link to code

关于类型的 typescript 传播运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58713097/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com