登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
12月21日就在北京,来看大模型推理 + 国产硬件生态 + 开源社区分享,一起搞技术、聊开源、领福利~~
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
3
Star
45
Fork
21
DreamCoders
/
CoderGuide
代码
Issues
1169
Pull Requests
0
Wiki
统计
流水线
服务
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
Typescript中泛型是什么?
待办的
#IAGA19
陌生人
拥有者
创建于
2024-07-29 16:16
<h2>一、是什么</h2> <p>泛型程序设计(generic programming)是程序设计语言的一种风格或范式</p> <p>泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 在<code>typescript</code>中,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性</p> <p>假设我们用一个函数,它可接受一个 <code>number</code> 参数并返回一个<code>number</code> 参数,如下写法:</p> <pre><code class="language-ts">function returnItem (para: number): number { return para }</code></pre> <p>如果我们打算接受一个 <code>string</code> 类型,然后再返回 <code>string</code>类型,则如下写法:</p> <pre><code class="language-ts">function returnItem (para: string): string { return para }</code></pre> <p>上述两种编写方式,存在一个最明显的问题在于,代码重复度比较高</p> <p>虽然可以使用 <code>any</code>类型去替代,但这也并不是很好的方案,因为我们的目的是接收什么类型的参数返回什么类型的参数,即在运行时传入参数我们才能确定类型</p> <p>这种情况就可以使用泛型,如下所示:</p> <pre><code class="language-ts">function returnItem<T>(para: T): T { return para }</code></pre> <p>可以看到,泛型给予开发者创造灵活、可重用代码的能力</p> <h2>二、使用方式</h2> <p>泛型通过<code><></code>的形式进行表述,可以声明:</p> <ul> <li> <p>函数</p> </li> <li> <p>接口</p> </li> <li> <p>类</p> </li> </ul> <h3>函数声明</h3> <p>声明函数的形式如下:</p> <pre><code class="language-ts">function returnItem<T>(para: T): T { return para }</code></pre> <p>定义泛型的时候,可以一次定义<strong>多个类型参数</strong>,比如我们可以同时定义泛型 <code>T</code> 和 泛型 <code>U</code>:</p> <pre><code class="language-ts">function swap<T, U>(tuple: [T, U]): [U, T] { return [tuple[1], tuple[0]]; } swap([7, 'seven']); // ['seven', 7]</code></pre> <h3>接口声明</h3> <p>声明接口的形式如下:</p> <pre><code class="language-ts">interface ReturnItemFn<T> { (para: T): T }</code></pre> <p>那么当我们想传入一个number作为参数的时候,就可以这样声明函数:</p> <pre><code class="language-ts">const returnItem: ReturnItemFn<number> = para => para</code></pre> <h3></h3> <h3>类声明</h3> <p>使用泛型声明类的时候,既可以作用于类本身,也可以作用与类的成员函数</p> <p>下面简单实现一个元素同类型的栈结构,如下所示:</p> <pre><code class="language-ts">class Stack<T> { private arr: T[] = [] public push(item: T) { this.arr.push(item) } public pop() { this.arr.pop() } }</code></pre> <p>使用方式如下:</p> <pre><code class="language-ts">const stack = new Stacn<number>()</code></pre> <p>如果上述只能传递 <code>string</code> 和 <code>number</code> 类型,这时候就可以使用 <code><T extends xx></code> 的方式猜实现<strong>约束泛型</strong>,如下所示:</p> <p><img src="https://static.ecool.fun//article/fab37f80-c8f9-48a9-ba72-2aa8c3af6b00.png" alt="" /></p> <p>除了上述的形式,泛型更高级的使用如下:</p> <p>例如要设计一个函数,这个函数接受两个参数,一个参数为对象,另一个参数为对象上的属性,我们通过这两个参数返回这个属性的值</p> <p>这时候就设计到泛型的索引类型和约束类型共同实现</p> <h3>索引类型、约束类型</h3> <p>索引类型 <code>keyof T</code> 把传入的对象的属性类型取出生成一个联合类型,这里的泛型 U 被约束在这个联合类型中,如下所示:</p> <pre><code class="language-ts">function getValue<T extends object, U extends keyof T>(obj: T, key: U) { return obj[key] // ok }</code></pre> <p>上述为什么需要使用泛型约束,而不是直接定义第一个参数为 <code>object</code>类型,是因为默认情况 <code>object</code> 指的是<code>{}</code>,而我们接收的对象是各种各样的,一个泛型来表示传入的对象类型,比如 <code>T extends object</code></p> <p>使用如下图所示:</p> <p><img src="https://static.ecool.fun//article/19ea7bdd-176b-4db7-9bdb-72d1318c6fea.png" alt="" /></p> <h3>多类型约束</h3> <p>例如如下需要实现两个接口的类型约束:</p> <pre><code class="language-ts">interface FirstInterface { doSomething(): number } interface SecondInterface { doSomethingElse(): string } </code></pre> <p>可以创建一个接口继承上述两个接口,如下:</p> <pre><code class="language-ts">interface ChildInterface extends FirstInterface, SecondInterface { }</code></pre> <p>正确使用如下:</p> <pre><code class="language-ts">class Demo<T extends ChildInterface> { private genericProperty: T constructor(genericProperty: T) { this.genericProperty = genericProperty } useT() { this.genericProperty.doSomething() this.genericProperty.doSomethingElse() } }</code></pre> <p>通过泛型约束就可以达到多类型约束的目的</p> <h2>三、应用场景</h2> <p>通过上面初步的了解,后述在编写 <code>typescript</code> 的时候,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性的时候,这种情况下就可以使用泛型</p> <p>灵活的使用泛型定义类型,是掌握<code>typescript</code> 必经之路</p>
<h2>一、是什么</h2> <p>泛型程序设计(generic programming)是程序设计语言的一种风格或范式</p> <p>泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 在<code>typescript</code>中,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性</p> <p>假设我们用一个函数,它可接受一个 <code>number</code> 参数并返回一个<code>number</code> 参数,如下写法:</p> <pre><code class="language-ts">function returnItem (para: number): number { return para }</code></pre> <p>如果我们打算接受一个 <code>string</code> 类型,然后再返回 <code>string</code>类型,则如下写法:</p> <pre><code class="language-ts">function returnItem (para: string): string { return para }</code></pre> <p>上述两种编写方式,存在一个最明显的问题在于,代码重复度比较高</p> <p>虽然可以使用 <code>any</code>类型去替代,但这也并不是很好的方案,因为我们的目的是接收什么类型的参数返回什么类型的参数,即在运行时传入参数我们才能确定类型</p> <p>这种情况就可以使用泛型,如下所示:</p> <pre><code class="language-ts">function returnItem<T>(para: T): T { return para }</code></pre> <p>可以看到,泛型给予开发者创造灵活、可重用代码的能力</p> <h2>二、使用方式</h2> <p>泛型通过<code><></code>的形式进行表述,可以声明:</p> <ul> <li> <p>函数</p> </li> <li> <p>接口</p> </li> <li> <p>类</p> </li> </ul> <h3>函数声明</h3> <p>声明函数的形式如下:</p> <pre><code class="language-ts">function returnItem<T>(para: T): T { return para }</code></pre> <p>定义泛型的时候,可以一次定义<strong>多个类型参数</strong>,比如我们可以同时定义泛型 <code>T</code> 和 泛型 <code>U</code>:</p> <pre><code class="language-ts">function swap<T, U>(tuple: [T, U]): [U, T] { return [tuple[1], tuple[0]]; } swap([7, 'seven']); // ['seven', 7]</code></pre> <h3>接口声明</h3> <p>声明接口的形式如下:</p> <pre><code class="language-ts">interface ReturnItemFn<T> { (para: T): T }</code></pre> <p>那么当我们想传入一个number作为参数的时候,就可以这样声明函数:</p> <pre><code class="language-ts">const returnItem: ReturnItemFn<number> = para => para</code></pre> <h3></h3> <h3>类声明</h3> <p>使用泛型声明类的时候,既可以作用于类本身,也可以作用与类的成员函数</p> <p>下面简单实现一个元素同类型的栈结构,如下所示:</p> <pre><code class="language-ts">class Stack<T> { private arr: T[] = [] public push(item: T) { this.arr.push(item) } public pop() { this.arr.pop() } }</code></pre> <p>使用方式如下:</p> <pre><code class="language-ts">const stack = new Stacn<number>()</code></pre> <p>如果上述只能传递 <code>string</code> 和 <code>number</code> 类型,这时候就可以使用 <code><T extends xx></code> 的方式猜实现<strong>约束泛型</strong>,如下所示:</p> <p><img src="https://static.ecool.fun//article/fab37f80-c8f9-48a9-ba72-2aa8c3af6b00.png" alt="" /></p> <p>除了上述的形式,泛型更高级的使用如下:</p> <p>例如要设计一个函数,这个函数接受两个参数,一个参数为对象,另一个参数为对象上的属性,我们通过这两个参数返回这个属性的值</p> <p>这时候就设计到泛型的索引类型和约束类型共同实现</p> <h3>索引类型、约束类型</h3> <p>索引类型 <code>keyof T</code> 把传入的对象的属性类型取出生成一个联合类型,这里的泛型 U 被约束在这个联合类型中,如下所示:</p> <pre><code class="language-ts">function getValue<T extends object, U extends keyof T>(obj: T, key: U) { return obj[key] // ok }</code></pre> <p>上述为什么需要使用泛型约束,而不是直接定义第一个参数为 <code>object</code>类型,是因为默认情况 <code>object</code> 指的是<code>{}</code>,而我们接收的对象是各种各样的,一个泛型来表示传入的对象类型,比如 <code>T extends object</code></p> <p>使用如下图所示:</p> <p><img src="https://static.ecool.fun//article/19ea7bdd-176b-4db7-9bdb-72d1318c6fea.png" alt="" /></p> <h3>多类型约束</h3> <p>例如如下需要实现两个接口的类型约束:</p> <pre><code class="language-ts">interface FirstInterface { doSomething(): number } interface SecondInterface { doSomethingElse(): string } </code></pre> <p>可以创建一个接口继承上述两个接口,如下:</p> <pre><code class="language-ts">interface ChildInterface extends FirstInterface, SecondInterface { }</code></pre> <p>正确使用如下:</p> <pre><code class="language-ts">class Demo<T extends ChildInterface> { private genericProperty: T constructor(genericProperty: T) { this.genericProperty = genericProperty } useT() { this.genericProperty.doSomething() this.genericProperty.doSomethingElse() } }</code></pre> <p>通过泛型约束就可以达到多类型约束的目的</p> <h2>三、应用场景</h2> <p>通过上面初步的了解,后述在编写 <code>typescript</code> 的时候,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性的时候,这种情况下就可以使用泛型</p> <p>灵活的使用泛型定义类型,是掌握<code>typescript</code> 必经之路</p>
评论 (
0
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
Typescript
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
未关联
master
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(1)
1
https://gitee.com/DreamCoders/CoderGuide.git
git@gitee.com:DreamCoders/CoderGuide.git
DreamCoders
CoderGuide
CoderGuide
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册