typescript - 将类型推送到元组的末尾
问题描述
我可以在元组的开头添加元素,或者从那里删除它
type ShiftTuple<T extends any[]> = ((...t: T) => void) extends ((x: infer X, ...r: infer R) => void) ? R : never;
type UnshiftTuple<X, T extends any[]> = ((x: X, ...t: T) => void) extends ((...r: infer R) => void) ? R : never;
但是我很难用最后一个元素而不是第一个元素做同样的事情。
即使我写了函数
function f<X, Z extends any[]>(x: X, ...args: Z) {
return [...args, x]
}
打字稿说它返回any[]
。
有没有办法将新类型推送到元组的末尾(不支持)
export type PushTuple<T extends any[], X> = [...T, X];
解决方案
TS4.0+ 更新
TypeScript 4.0 引入了variadic tuple typesPush
,它以更直接的方式支持ing 到 tuple 的末尾......就像这样:
type Push<T extends readonly any[], V> = [...T, V];
TS3.9-的旧答案:
我通常Push
根据您所称的内容Unshift
(但我称其为Cons
)来定义,如下所示:
type Cons<H, T extends readonly any[]> =
((head: H, ...tail: T) => void) extends ((...cons: infer R) => void) ? R : never;
type Push<T extends readonly any[], V>
= T extends any ? Cons<void, T> extends infer U ?
{ [K in keyof U]: K extends keyof T ? T[K] : V } : never : never;
可行的方法Push<T, V>
是使元组的一个元素比T
(它用它做的Cons
)长一个元素,然后映射到它上面。它用来自 的相应元素填充输出的初始元素T
,然后填充它剩下的任何内容V
。长度为n+1的映射元组中唯一 不是长度为 n 的元组的索引的元素索引是索引n本身,因此这意味着新元组的最后一个元素是V
。(我确保分发过来T
,以防它是一个工会。)
请注意,这仅适用于非边缘情况...不要期望readonly
、optional和rest元组元素或非元组数组表现良好;如果你想定义它,你必须自己解决这些限制。
恢复常规答案:
那么你可以f()
这样定义:
function f<X, Z extends any[]>(x: X, ...args: Z): Push<Z, X>;
function f(x: any, ...args: any[]): any[] {
return [...args, x]
}
(请注意,我使用重载让自己不必担心编译器会尝试并且无法理解实现符合Push<Z, X>
:
它可以按您的预期工作:
const s = f(4, "hey", false);
// const s: [string, boolean, number]
console.log(s); // ["hey", false, 4]
好的,希望有帮助;祝你好运!
推荐阅读
- python - Tkinter Checkbuttons 之间的纠缠
- reactjs - Expo 无法在 Typescript 中的 Visual Studio 代码上自动导入 React-native
- android - 如何在不克隆整个 android 库的情况下在 Android Studio 中构建部分 Android 源代码?
- typescript - 如何输入这个 Maybe 函子?
- excel - 动态查找单元格中的多个值(逗号分隔)并将相应的 ID 返回到单个单元格(逗号分隔)
- c# - Windows 服务中的连续异步 Ping
- python - 如何定义具有列表属性的 python 类和接受可变参数的类构造函数?
- python - 如何停止分配前引用的 UnboundLocalError
- tensorflow - 如何使用所有 cpu 核心在 keras 中训练模型
- python - 如何使用从小部件文本框中输入的单词来搜索数据框,然后使用 python、ipywidgets 显示搜索结果?