首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

带有ArgumentTypes的带n参数的Typescript类型安全curry函数

是一种函数式编程的概念,用于创建一个可以部分应用参数的函数,并返回一个新的函数,以便稍后传入剩余的参数。Typescript类型安全curry函数可以确保在编译时捕获参数类型错误,提高代码的可靠性和可维护性。

该函数的定义如下:

代码语言:txt
复制
type Curry<Fn extends (...args: any[]) => any> = 
    <P extends any[]>(...args: P) => 
        ArgumentTypes<Fn, P> extends infer A ? 
            A extends any[] ? 
                ReturnType<Fn> extends infer R ? 
                    R extends Promise<any> ? 
                        Promise<Curry<(...args: A) => R>> : 
                        Curry<(...args: A) => R> : 
                    never : 
                never : 
            never;

type ArgumentTypes<Fn extends (...args: any[]) => any, P extends any[]> = 
    P extends [...infer A, ...any[]] ? 
        A : 
        never;

function curry<Fn extends (...args: any[]) => any>(fn: Fn): Curry<Fn> {
    return (...args) => {
        if (args.length >= fn.length) {
            return fn(...args);
        } else {
            return curry((...rest) => fn(...args, ...rest));
        }
    };
}

这个curry函数可以接受一个函数作为参数,并返回一个新的函数。新函数可以接受任意数量的参数,并在参数数量满足原函数的要求时执行原函数。如果参数数量不足,则返回一个新的函数,继续接受剩余的参数,直到参数数量满足要求。

使用curry函数的优势是可以方便地创建可复用的函数,通过部分应用参数来生成新的函数。这样可以减少重复的代码,并提高代码的可读性和可维护性。

应用场景:

  • 函数柯里化:通过curry函数可以将一个多参数的函数转化为一系列单参数的函数,方便函数的组合和复用。
  • 部分应用参数:可以通过curry函数预先设置一部分参数,生成一个新的函数,方便在后续调用中只传递剩余的参数。
  • 函数组合:curry函数可以与其他函数组合使用,实现更复杂的功能。

腾讯云相关产品和产品介绍链接地址:

  • 云函数(Serverless):https://cloud.tencent.com/product/scf
  • 云开发(CloudBase):https://cloud.tencent.com/product/tcb
  • 云数据库(TencentDB):https://cloud.tencent.com/product/cdb
  • 云存储(COS):https://cloud.tencent.com/product/cos
  • 人工智能(AI):https://cloud.tencent.com/product/ai
  • 物联网(IoT):https://cloud.tencent.com/product/iotexplorer
  • 区块链(Blockchain):https://cloud.tencent.com/product/baas
  • 视频处理(VOD):https://cloud.tencent.com/product/vod
  • 音视频通信(TRTC):https://cloud.tencent.com/product/trtc
  • 网络安全(SSL证书):https://cloud.tencent.com/product/ssl
  • 移动开发(移动推送):https://cloud.tencent.com/product/tpns
  • 元宇宙(Tencent XR):https://cloud.tencent.com/product/xr
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Kotlin】函数类型 ( 函数类型 | 参数名称参数列表 | 可空函数类型 | 复杂函数类型 | 接收者函数类型 | 函数类型别名 | 函数类型实例化 | 函数调用 )

函数类型 II . 参数参数列表 III . 可空函数类型 IV . 复杂函数类型解读 V . 函数类型别名 VI . 接收者类型 函数类型 VII . 函数类型实例化 VIII ....只有参数类型函数类型 : 参数列表中只有参数类型 ; ( 参数类型1 , 参数类型2 , … 参数类型n ) -> 返回值类型 3 ....有参数名称函数类型 : 参数列表中每个元素都由 参数名称 : 参数类型 组成 , 多个列表元素使用逗号隔开 ; ( 参数名称1 : 参数类型1 , 参数名称2 : 参数类型2 , … 参数名称n :...参数类型n ) -> 返回值类型 4 ....接收者函数类型 与 不带接收者函数类型 之间转换 ---- 接收者函数类型 , 可以转换为 不带接收者函数类型 , 转换规则是 , 接收者函数类型接收者 , 可以转换为不带接收者类型第一个参数

2.7K10

TypeScript4有些啥?

通过组合一些已经存在可变函数, 例如f(...args: [...T]), 就能够把函数参数当做数组来看待, 进而能够比现在更具弹性地去描述函数参数格式....举个例子, 目前对函数中剩余/可变参数描述必须始终放在函数参数描述末尾, f(a: number, ...b:string[], c: boolean)便是一个无效例子 在这一次升级之后, 通过在函数参数定义中使用可变元组类型..., 而不仅仅是对象 对可变参数函数进行完整类型提示 对复杂, 部分参数类型已知可变参数进行正确提示 对Promisify进行完整类型定义 对诸如curry, apply, compose等高阶函数进行完整地参数类型描述...标注元组 Labelled Tuples 这是一个跟上一个有关系, 但是要简单得多特性: TypeScript将允许给元组中元素加上标注了....至少它们帮着TypeScript程序员们续命了 -- 改善了类型安全以及开发体验.

93710
  • map实现和柯里化(Currying)

    一般情况下算子可能指输入中带有函数情况,而对于输出中带有函数带有输入参数信息,我们很多情况下习惯叫闭包。...map算子(高阶函数)是想同时处理n个长度相同array或list等,它输入参数中存在一个参数函数。 ?   ...如图以一个简单例子来演示map作用,4个参数,一个参数是一个带有三个参数函数f,另外三个参数是长度一样list a、b、c。...我们先来做这个抽象,我们希望这样用,(scan s f),两个参数,一个是s是一个list,另一个是f,结果是一个和s等长度list,它元素和s元素一一对应,由函数f转换而来。   ...在此,我们希望设计一个函数来实现柯里化,curry(n ,f),其中f为希望柯里化函数,而n为f参数个数。   比如之前g则为curry(3, add)。

    85420

    JavaScript: 函数式编程-类型签名

    现在我们可以看出 match 这个函数接受一个 Regex 作为参数,返回一个从 String 到 [String] 函数。...因为curry,造成结果就是这样:给 match 函数一个 Regex,得到一个新函数,能够处理其 String 参数。...,我们可以知道 TypeScript 是借鉴类类似于类型签名思想去做类型检测,以至于我们使用 JavaScript 时候更加方便。...具体 TypeScript 基础函数类型定义可以看看我文章 TypeScript 基本类型和泛型使用 缩小可能性范围 narrowing of possibility 一旦引入一个类型变量,就会出现一个奇怪特性叫做...我们除了知道参数是个数组,其他一概不知;所以函数功能就只限于操作这个数组上。在它对 a 一无所知情况下,它可能对 a 做什么操作呢?

    83110

    TypeScript 条件类型精读与实践

    TypeScript 也不例外,使用条件类型可以描述输入类型与输出类型之间关系。 本文同步首发在个人博客中,欢迎订阅、交流。...工具类型 心细读者可能已经发现了 Demo 类型声明过程其实就是 TypeScript 官方提供工具类型中 Exclude 实现原理,其用于将联合类型...true : false) 在 TypeScript 类型定义中,若在箭头函数中使用 extends 也是同理,由于从左向右阅读习惯,也会导致阅读者对类型代码执行顺序感到困惑。...Curry, R> : R 因此在箭头函数中使用 extends 建议加上括号,对于进行 code review 有很大帮助。...Curry, R> : R) 结合类型推导使用条件类型TypeScript 中,一般会结合 extends 来使用类型推导 infer 语法。使用它可以实现自动推导类型目的。

    71920

    Typescript 类型本质是什么

    第二种是泛型静态类型系统,泛型也叫类型参数,具体类型可以通过泛型参数来动态确定,多了一定灵活性。...Tuple : RepeatN; 它作用是当传入泛型参数时,返回该参数重复 n元组: type res = RepeactN<'a', 3...首先,函数参数在 ts 类型里就是泛型参数,变量在 ts 类型里也用泛型参数来存储,循环在 ts 类型利用递归来实现,所以就是这样: 首先定义类型,Item 是重复目标, n 是个数,然后第三个参数...Tuple : RepeatN; 通过这个高级类型我们可以感受到,typescript 静态类型系统就是第三种,可以支持类型编程,可以实现各种复杂逻辑...javascript 就是动态类型语言,虽然写代码比较简单,但是运行时很容易出类型安全问题,typescript 就是解决了 javascript 没有静态类型系统问题而做扩展。

    1.4K10

    Typescript 类型本质是什么

    第二种是泛型静态类型系统,泛型也叫类型参数,具体类型可以通过泛型参数来动态确定,多了一定灵活性。...Tuple : RepeatN; 它作用是当传入泛型参数时,返回该参数重复 n元组: type res = RepeactN<'a', 3...首先,函数参数在 ts 类型里就是泛型参数,变量在 ts 类型里也用泛型参数来存储,循环在 ts 类型利用递归来实现,所以就是这样: 首先定义类型,Item 是重复目标, n 是个数,然后第三个参数...Tuple : RepeatN; 通过这个高级类型我们可以感受到,typescript 静态类型系统就是第三种,可以支持类型编程,可以实现各种复杂逻辑...javascript 就是动态类型语言,虽然写代码比较简单,但是运行时很容易出类型安全问题,typescript 就是解决了 javascript 没有静态类型系统问题而做扩展。

    1.6K30

    JavaScript高阶函数

    至少满足下列条件之一函数 可以作为参数被传递 可以作为返回值输出 应用场景 作为参数传递 回调函数 ajax 异步请求完成之后执行 var getUserInfo = function( userId...,这些跟业务逻辑无关功能通常包括日志统计、安全控制、异常处理等 可以保持业务逻辑模块纯净和高内聚性 在 JavaScript中实现 AOP,都是指把一个函数“动态植入”到另外一个函数之中,例如扩展...一个currying函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入参数函数形成闭包中被保存起来。...待到函数被真正需要求值时候,之前传入所有参数都会被一次性用于求值。...(1)); console.log(curry(1)(2)); console.log(curry(1)(2)(3)); 专门定义一个函数,对上面解法参数进行柯里化⬇️ var curry = function

    45120

    前端反卷计划-组件库-01-环境搭建

    我起组件库名称是叫:curry-design首先去 npm 仓库查找curry-design,看有没有人在使用。。https://www.npmjs.com/search?...q=curry-design图片从结果可以看到,这个名字没有其他包在用,所以我可以使用这个名字作为组件库包名。如果你起名字,在npm里面查询到,则需要换个名字。...创建项目使用create-react-app创建项目在终端执行如下命令: npx create-react-app curry-design --template typescript执行后,就会下载成功...使用 React 推荐规则 'plugin:@typescript-eslint/recommended', // 使用 TypeScript 推荐规则 ], parser: '@typescript-eslint...,在根目录创建.prettierrc.js,在这个文件进行配置module.exports = { // 箭头函数只有一个参数时候可以忽略括号 arrowParens: 'avoid', //

    24630

    Vue 3.0前 TypeScript 最佳入门实践

    泛型与 Any Ts 特殊类型 Any 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然: // 方法一:带有any参数方法 function any_func(arg: any):...因为 any可以代替任意类型,所以该方法在传入参数不是数组或者带有 length属性对象时,会抛出异常。...例如给函数传入参数对象中只有部分属性赋值了。带有可选属性接口与普通接口定义差不多,只是在可选属性名字定义后面加一个 ?符号。...但是,解释器读到函数修饰符“@”时候,后面步骤会是这样: 去调用 test函数, test函数入口参数就是那个叫“ func”函数; test函数被执行,入口参数(也就是 func函数...)会被调用(执行); 换言之,修饰符那个函数入口参数,就是下面的那个整个函数

    3.4K20

    深入理解函数式编程(上)

    比如下面这个简单演算式: 图 8 第一次函数调用传入m=5,返回一个新函数,这个新函数接收一个参数n,并返回m + n结果。...听起来有点绕口,但是它实际上就是函数调用参数替换。比如: 图 10 可以使用1替换m,3替换n,那么整个表达式可以化简为4。这也是函数式编程里面的引用透明性由来。...我们在JavaScript中有很多创建函数方式: 图 16 虽然函数有这么多定义,但function关键字声明函数带有arguments和this关键字,这让他们看起来更像是对象方法(method...如果用Typescript表示我们数据流动就是: 图 27 用Haskell表示更简洁,后面都用Haskell类型表示方式,作为我们符号语言。...记住,任何时候我们都可以重构代码,通过良好设计来解决栈溢出问题。 2.5.7 类型推导 当前JS有TypeScript加持,也可以算是有类型推导了。

    80630

    【Vuejs】301- Vue 3.0前 TypeScript 最佳入门实践

    泛型与 Any Ts 特殊类型 Any 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然: // 方法一:带有any参数方法 function any_func(arg: any):...因为 any可以代替任意类型,所以该方法在传入参数不是数组或者带有 length属性对象时,会抛出异常。...例如给函数传入参数对象中只有部分属性赋值了。带有可选属性接口与普通接口定义差不多,只是在可选属性名字定义后面加一个 ?符号。...但是,解释器读到函数修饰符“@”时候,后面步骤会是这样: 去调用 test函数, test函数入口参数就是那个叫“ func”函数; test函数被执行,入口参数(也就是 func函数...)会被调用(执行); 换言之,修饰符那个函数入口参数,就是下面的那个整个函数

    4.4K52

    Scala控制抽象

    这个函数需要两个String参数,不过你不需要指定参数类型。...List上调用高阶函数exists def containsNeg(nums: List[Int] = nums.exists(_<0) Curry化 展示了curry化后同一个函数。...代之以一个列表两个Int参数,你把这个函数应用于两个列表各一个参数 ? 在第一个函数上应用1——换句话说,调用第一个函数并传入1——会产生第二个函数,在第二个函数上应用2产生结果 ?...first和second函数只是curry化过程一个演示。他们并不直接连接在curriedSum函数上。尽管如此,仍然有一个方式获得实际指向curriedSum“第二个”函数参考。...编写新控制结构: op类型是Double => Double,就是说它是一个Double做参数并返回另一个Double函数。 ?

    47720

    3w字长文带你【从0开发一个自己前端组件库】 | 技术创作特训营第五期

    我起组件库名称是叫:curry-design 首先去 npm 仓库查找curry-design,看有没有人在使用。。 https://www.npmjs.com/search?...q=curry-design 从结果可以看到,这个名字没有其他包在用,所以我可以使用这个名字作为组件库包名。 如果你起名字,在npm里面查询到,则需要换个名字。...创建项目 使用create-react-app创建项目 在终端执行如下命令: npx create-react-app curry-design --template typescript 执行后,就会下载成功...比如上面代码中@include button-size 函数,这个是scss一个特性,可以从官网上看下介绍。...新建 src/styles/_mixin.scss,编写如下代码: 这里解释一下:相当于在button-size中传了4个参数,使用这4个参数来定义样式属性,使用时候即可传入对应样式变量即可。

    72951

    Vue 3.0前 TypeScript 最佳入门实践

    泛型与 Any Ts 特殊类型 Any 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然: // 方法一:带有any参数方法 function any_func(arg: any):...因为 any可以代替任意类型,所以该方法在传入参数不是数组或者带有 length属性对象时,会抛出异常。...例如给函数传入参数对象中只有部分属性赋值了。带有可选属性接口与普通接口定义差不多,只是在可选属性名字定义后面加一个 ?符号。...但是,解释器读到函数修饰符“@”时候,后面步骤会是这样: 去调用 test函数, test函数入口参数就是那个叫“ func”函数; test函数被执行,入口参数(也就是 func函数...)会被调用(执行); 换言之,修饰符那个函数入口参数,就是下面的那个整个函数

    2.4K20

    28. Groovy 闭包知识学习-第三篇 终篇

    4.1 局部套用-curray 在Groovy中,套用指的是部分应用概念。由于Groovy对闭包应用了不同作用域规则,所以它并不符合函数式编程中curry真正概念。...在Groovy中curry将允许您设置闭包一个参数值,它将返回一个接受一个少参数新闭包。...println twice('zinyan')==nCopies(2,'zinyan') //输出:true 例如上面的示例中,我们本来需要往闭包中传入两个参数,但是我使用curry只传入最左边参数...右侧套用:类似于左curry,可以设置闭包最右边参数,使用关键方法为rcurry: def nCopies = { int n, String str -> str*n } def blah...如果一个函数(闭包)计算很慢,但这个函数将经常使用相同参数被调用。 一个典型例子是斐波那契集合。

    89630

    Vue 3.0前 TypeScript 最佳入门实践

    泛型与 Any Ts 特殊类型 Any 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然: // 方法一:带有any参数方法 function any_func(arg: any):...因为 any可以代替任意类型,所以该方法在传入参数不是数组或者带有 length属性对象时,会抛出异常。...例如给函数传入参数对象中只有部分属性赋值了。带有可选属性接口与普通接口定义差不多,只是在可选属性名字定义后面加一个 ?符号。...但是,解释器读到函数修饰符“@”时候,后面步骤会是这样: 去调用 test函数, test函数入口参数就是那个叫“ func”函数; test函数被执行,入口参数(也就是 func函数...)会被调用(执行); 换言之,修饰符那个函数入口参数,就是下面的那个整个函数

    2.6K31

    快速了解typescript语法

    ('My name is muyy') } 二、函数 ---- 为函数定义类型 我们可以给每个参数添加类型之后再为函数本身添加返回值类型。...TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。下面函数 add, add2, add3 效果是一样,其中是 add3 函数函数完整类型。...如果默认值参数出现在必须参数前面,用户必须明确传入 undefined 值来获得默认值。...例如,我们重写上例子,让 firstName 是默认值参数: function buildName2(firstName = "鸣", lastName?...除了描述带有属性普通对象外,接口也可以描述函数类型。定义函数类型接口就像是一个只有参数列表和返回值类型函数定义。参数列表里每个参数都需要名字和类型

    85720
    领券