深入浅出 Typescript
<p>TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准。</p><p>TypeScript 由微软开发的自由和开源的编程语言。</p>
<p>TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。</p>
<p>以上为网上对 Typescript 的一些解释,那我们为什么要学 Typescript?</p>
<p>提到前端我们首先会想到 HTML,CSS,JavaScript 三大家族,我们掌握这三个就可以在前端界获得一席之地,怎么突然又冒出个 Typescript,真心是学不动了,但是众所周知,Vue 创始人尤雨溪尤大大已经宣布 Vue3.x 代码库将使用 Typescript 编写,并且在知乎上对于"Typescript 不适合在 Vue 开发业务中使用吗?" 的提问中做出回答,传送门:https://www.zhihu.com/question/310485097/answer/591869966,Vue 又是现在国内主流的前端框架之一,只能说,如果不学 Typescript,尤大大都救不了你了。</p>
<div>
<p>众所周知,从本质上来说,JavaScript是一种自由松散语言,它的语法规则并不是那么严格。正因为如此,我们就更容易犯错,而且,即使是在运行的时候,我们也不能找到所有的错误。鉴于此,TypeScript作为JavaScript的增强版,它的语法更严格,我们在编写代码的时候就能够发现大部分错误。不仅如此,按照TypeScript官方的说法,TypeScript使得我们能够以JavaScript的方式实现自己的构思。TypeScript对面向对象的支持也非常完善,它拥有面向对象编程语言的所有特性。</p>
<p>TypeScript最大的目的是让程序员更具创造性,提高生产力,它将极大增强JavaScript编写应用的开发和调试环节,让JavaScript能够方便用于编写大型应用和进行多人协作。</p>
<p>不过目前最后运行时还需要将TypeScript编译为JavaScript。</p>
<p>那接下来我们就来看看如何安装使用 Typescript。</p>
<p>在安装 Typescript 之前我们要先安装 NodeJs,然后运行</p>
<div class="cnblogs_code">
<pre>npm install -g typescript</pre>
</div>
<p class="blockParagraph-544a408c" data-key="a9388847bc354f57921886c651eabc52"><span class="text-4505230f--TextH400-3033861f--textContentFamily-49a318e1"><span data-key="18ea10dde3124bdab460f5611bc70143"><span data-offset-key="18ea10dde3124bdab460f5611bc70143:0">以上命令会在全局环境下安装 <span data-offset-key="18ea10dde3124bdab460f5611bc70143:1"><code class="code-81e98f88" data-slate-leaf="true">tsc</code><span data-offset-key="18ea10dde3124bdab460f5611bc70143:2"> 命令,安装完成之后,我们就可以在任何地方执行 <span data-offset-key="18ea10dde3124bdab460f5611bc70143:3"><code class="code-81e98f88" data-slate-leaf="true">tsc</code><span data-offset-key="18ea10dde3124bdab460f5611bc70143:4"> 命令了。</span></span></span></span></span></span></span></p>
<p class="blockParagraph-544a408c" data-key="7f6eb2ef5c8d4674ae42537b14510c49" data-slate-fragment="JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFNCVCQiVBNSVFNCVCOCU4QSVFNSU5MSVCRCVFNCVCQiVBNCVFNCVCQyU5QSVFNSU5QyVBOCVFNSU4NSVBOCVFNSVCMSU4MCVFNyU4RSVBRiVFNSVBMiU4MyVFNCVCOCU4QiVFNSVBRSU4OSVFOCVBMyU4NSUyMCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjJ0c2MlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMm1hcmslMjIlMkMlMjJ0eXBlJTIyJTNBJTIyY29kZSUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlN0QlNUQlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiUyMCVFNSU5MSVCRCVFNCVCQiVBNCVFRiVCQyU4QyVFNSVBRSU4OSVFOCVBMyU4NSVFNSVBRSU4QyVFNiU4OCU5MCVFNCVCOSU4QiVFNSU5MCU4RSVFRiVCQyU4QyVFNiU4OCU5MSVFNCVCQiVBQyVFNSVCMCVCMSVFNSU4RiVBRiVFNCVCQiVBNSVFNSU5QyVBOCVFNCVCQiVCQiVFNCVCRCU5NSVFNSU5QyVCMCVFNiU5NiVCOSVFNiU4OSVBNyVFOCVBMSU4QyUyMCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjJ0c2MlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMm1hcmslMjIlMkMlMjJ0eXBlJTIyJTNBJTIyY29kZSUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlN0QlNUQlN0QlMkMlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiUyMCVFNSU5MSVCRCVFNCVCQiVBNCVFNCVCQSU4NiVFMyU4MCU4MiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTdEJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyaXNWb2lkJTIyJTNBZmFsc2UlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRTclQkMlOTYlRTglQUYlOTElRTQlQjglODAlRTQlQjglQUElMjBUeXBlU2NyaXB0JTIwJUU2JTk2JTg3JUU0JUJCJUI2JUU1JUJFJTg4JUU3JUFFJTgwJUU1JThEJTk1JUVGJUJDJTlBJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlNUQlN0QlNUQlN0Q="><span class="text-4505230f--TextH400-3033861f--textContentFamily-49a318e1">编译一个 TypeScript 文件很简单:</span></p>
<div class="cnblogs_code">
<pre>tsc demo.ts</pre>
</div>
<p><span data-offset-key="092c966047a348d1a407b8f67c10e885:0">运行上面的代码,我们就可以将 demo.ts 生成一个可以让浏览器解析的 demo.js 的文件。</span></p>
<p><span data-offset-key="092c966047a348d1a407b8f67c10e885:0">我们约定使用 TypeScript 编写的文件以 <span data-offset-key="092c966047a348d1a407b8f67c10e885:1"><code class="code-81e98f88" data-slate-leaf="true">.ts</code><span data-offset-key="092c966047a348d1a407b8f67c10e885:2"> 为后缀,用 TypeScript 编写 React 时,以 <span data-offset-key="092c966047a348d1a407b8f67c10e885:3"><code class="code-81e98f88" data-slate-leaf="true">.tsx</code><span data-offset-key="092c966047a348d1a407b8f67c10e885:4" data-slate-fragment="JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFNiU4OCU5MSVFNCVCQiVBQyVFNyVCQSVBNiVFNSVBRSU5QSVFNCVCRCVCRiVFNyU5NCVBOCUyMFR5cGVTY3JpcHQlMjAlRTclQkMlOTYlRTUlODYlOTklRTclOUElODQlRTYlOTYlODclRTQlQkIlQjYlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmNvZGUlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjAlRTQlQjglQkElRTUlOTAlOEUlRTclQkMlODAlRUYlQkMlOEMlRTclOTQlQTglMjBUeXBlU2NyaXB0JTIwJUU3JUJDJTk2JUU1JTg2JTk5JTIwUmVhY3QlMjAlRTYlOTclQjYlRUYlQkMlOEMlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzeCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybWFyayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJjb2RlJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCU3RCU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIwJUU0JUI4JUJBJUU1JTkwJThFJUU3JUJDJTgwJUUzJTgwJTgyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlNUQlN0QlNUQlN0Q="> 为后缀。</span></span></span></span></span></p>
<p><span data-offset-key="092c966047a348d1a407b8f67c10e885:0"><span data-offset-key="092c966047a348d1a407b8f67c10e885:1"><span data-offset-key="092c966047a348d1a407b8f67c10e885:2"><span data-offset-key="092c966047a348d1a407b8f67c10e885:3"><span data-offset-key="092c966047a348d1a407b8f67c10e885:4" data-slate-fragment="JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFNiU4OCU5MSVFNCVCQiVBQyVFNyVCQSVBNiVFNSVBRSU5QSVFNCVCRCVCRiVFNyU5NCVBOCUyMFR5cGVTY3JpcHQlMjAlRTclQkMlOTYlRTUlODYlOTklRTclOUElODQlRTYlOTYlODclRTQlQkIlQjYlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmNvZGUlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjAlRTQlQjglQkElRTUlOTAlOEUlRTclQkMlODAlRUYlQkMlOEMlRTclOTQlQTglMjBUeXBlU2NyaXB0JTIwJUU3JUJDJTk2JUU1JTg2JTk5JTIwUmVhY3QlMjAlRTYlOTclQjYlRUYlQkMlOEMlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzeCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybWFyayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJjb2RlJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCU3RCU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIwJUU0JUI4JUJBJUU1JTkwJThFJUU3JUJDJTgwJUUzJTgwJTgyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlNUQlN0QlNUQlN0Q=">那么我们在编写代码的时候不能每次都手动编译 .ts 文件,我们想要的是实时编译 .ts 文件,接下来我们就以 webstorm 编辑器来使 .ts 文件进行实时编译。其他编辑器可自行百度如何实时编译。</span></span></span></span></span></p>
<p><span data-offset-key="092c966047a348d1a407b8f67c10e885:0"><span data-offset-key="092c966047a348d1a407b8f67c10e885:1"><span data-offset-key="092c966047a348d1a407b8f67c10e885:2"><span data-offset-key="092c966047a348d1a407b8f67c10e885:3"><span data-offset-key="092c966047a348d1a407b8f67c10e885:4" data-slate-fragment="JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFNiU4OCU5MSVFNCVCQiVBQyVFNyVCQSVBNiVFNSVBRSU5QSVFNCVCRCVCRiVFNyU5NCVBOCUyMFR5cGVTY3JpcHQlMjAlRTclQkMlOTYlRTUlODYlOTklRTclOUElODQlRTYlOTYlODclRTQlQkIlQjYlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmNvZGUlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjAlRTQlQjglQkElRTUlOTAlOEUlRTclQkMlODAlRUYlQkMlOEMlRTclOTQlQTglMjBUeXBlU2NyaXB0JTIwJUU3JUJDJTk2JUU1JTg2JTk5JTIwUmVhY3QlMjAlRTYlOTclQjYlRUYlQkMlOEMlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzeCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybWFyayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJjb2RlJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCU3RCU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIwJUU0JUI4JUJBJUU1JTkwJThFJUU3JUJDJTgwJUUzJTgwJTgyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlNUQlN0QlNUQlN0Q=">webstorm 版本:</span></span></span></span></span></p>
<p><span data-offset-key="092c966047a348d1a407b8f67c10e885:0"><span data-offset-key="092c966047a348d1a407b8f67c10e885:1"><span data-offset-key="092c966047a348d1a407b8f67c10e885:2"><span data-offset-key="092c966047a348d1a407b8f67c10e885:3"><span data-offset-key="092c966047a348d1a407b8f67c10e885:4" data-slate-fragment="JTdCJTIyb2JqZWN0JTIyJTNBJTIyZG9jdW1lbnQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJibG9jayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJwYXJhZ3JhcGglMjIlMkMlMjJpc1ZvaWQlMjIlM0FmYWxzZSUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMm9iamVjdCUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFNiU4OCU5MSVFNCVCQiVBQyVFNyVCQSVBNiVFNSVBRSU5QSVFNCVCRCVCRiVFNyU5NCVBOCUyMFR5cGVTY3JpcHQlMjAlRTclQkMlOTYlRTUlODYlOTklRTclOUElODQlRTYlOTYlODclRTQlQkIlQjYlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlN0IlMjJvYmplY3QlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmNvZGUlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTVEJTdEJTJDJTdCJTIyb2JqZWN0JTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjAlRTQlQjglQkElRTUlOTAlOEUlRTclQkMlODAlRUYlQkMlOEMlRTclOTQlQTglMjBUeXBlU2NyaXB0JTIwJUU3JUJDJTk2JUU1JTg2JTk5JTIwUmVhY3QlMjAlRTYlOTclQjYlRUYlQkMlOEMlRTQlQkIlQTUlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyLnRzeCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIyb2JqZWN0JTIyJTNBJTIybWFyayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJjb2RlJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiU3RCU3RCU1RCU3RCUyQyU3QiUyMm9iamVjdCUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIwJUU0JUI4JUJBJUU1JTkwJThFJUU3JUJDJTgwJUUzJTgwJTgyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlNUQlN0QlNUQlN0Q="><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223145658594-979556618.png" alt="" width="139" height="119"></span></span></span></span></span></p>
<p>创建一个 demo 项目,然后在项目中创建一个 tsconfig.json 的文件,内容如下:</p>
<p>这里只是简单的配置,详细参数配置:https://www.tslang.cn/docs/handbook/tsconfig-json.html</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191225162156268-485759307.png" alt=""></p>
<p> </p>
<div>
<div>
<p>打开Webstorm,为TypeScript文件更改编译设置,File->Settings->Tool->File Watchers->TypeScript,这里我们需要选择TypeScript,但是File Watchers下默认是不存在的。需要点击右侧“+”号,选择,弹出 New Watcher,设置好圈红线的部分,点击ok。勾选“TypeScript”,点击ok。</p>
</div>
<img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223150549420-1114228241.png" alt="" width="909" height="451"></div>
<div> </div>
<img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223150906459-779208937.png" alt="" width="619" height="362">
<p> </p>
<p> <img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223150952866-1735078285.png" alt=""></p>
<p>File->Settings->Languages & Frameworks->TypeScript</p>
<p> <img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223151112542-1950912305.png" alt="" width="669" height="375"></p>
<p> </p>
<p> 根据上面的操作我们就可以实时编译 .ts 文件了。</p>
<p>目录结构如下,在 index.html 中银润 test.js</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223151635528-939295665.png" alt=""></p>
<p>test.ts 会实时编译为 test.js 文件。</p>
<p>test.ts</p>
<img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223151556970-1973278878.png" alt=""></div>
<div> </div>
<div>test.js </div>
<div><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191225122902680-69227269.png" alt="">
<p> </p>
<p>index.html 开发者工具中的打印日志</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191225123039836-908399233.png" alt=""></p>
<p> 根据上面的步骤我们就可以对 ts 文件进行实时编译了,接下来我们就来看一下 Typescript 的一些基本用法。</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191223154728791-2092706462.png" alt="" width="229" height="213"></p>
<p> 从上图我们可以看出 Typescript 包含了 ES6 和 ES5,那我们就可以在 typescript 中使用 es5 和 es6,同时进行了扩展,语法上跟我们之前讲的 Java 语法有很多相似。</p>
<p> </p>
<p><span style="font-size: 14pt"><strong>Typescript 基础类型</strong></span></p>
<p>Typescript 基础类型有:布尔类型(boolean)、数字类型(number)、字符串类型(string)、数组类型(array)、元组类型(tuple)、枚举类型(enum)、任意类型(any)、null 和 undefined 、void、never 类型等,接下来我们就一一来看一下这些类型的应用。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 在定义完参数进行赋值时,
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 必须按照给定的参数类型进行赋值
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 否则会出现编译问题
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * 但在页面当中还是会进行编译
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)"> * 但是不提倡这么做
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> boolean</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> let flag: <span style="color: rgba(0, 0, 255, 1)">boolean</span> = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> console.log(flag); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let flag1:boolean = 123; // Type '123' is not assignable to type 'boolean'.</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> number</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> let num: number = 123<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> console.log(num); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 123</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> string</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> let str: string = "abc"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">19</span> console.log(str); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> abc</span>
<span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> array 两种定义方式</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> let arrS: string[] = ["123", "abc"]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数组内元素必须为 string</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> let arrA: Array<number> = ; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数组内元素必须为 number</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> console.log(arrS); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ["123", "abc"]</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> console.log(arrA); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
<span style="color: rgba(0, 128, 128, 1)">26</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> tuple 元祖类型,属于数组的一种,可以为每个元素指定类型</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> let tup: = ;
</span><span style="color: rgba(0, 128, 128, 1)">29</span> console.log(tup); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
<span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let tup1: = ["abc",123];// 报错</span>
<span style="color: rgba(0, 128, 128, 1)">31</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> enum 枚举类型</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 128, 0, 1)"> * 在日常生活或者开发中
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 128, 0, 1)"> * 很多都不能或者不容易使用数据表达
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 128, 0, 1)"> * 如:颜色,日期,角色,性别等
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 128, 0, 1)"> * 例如在开发中我们常用 -1 表示 error,用 0 表示 success
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 128, 0, 1)"> * 这个就可以成为枚举
</span><span style="color: rgba(0, 128, 128, 1)">39</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)">enum Flag {
</span><span style="color: rgba(0, 128, 128, 1)">41</span> error = -1<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">42</span> success = 0
<span style="color: rgba(0, 128, 128, 1)">43</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">44</span>
<span style="color: rgba(0, 128, 128, 1)">45</span> let e: Flag =<span style="color: rgba(0, 0, 0, 1)"> Flag.error;
</span><span style="color: rgba(0, 128, 128, 1)">46</span> console.log(e); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> -1</span>
<span style="color: rgba(0, 128, 128, 1)">47</span>
<span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 128, 0, 1)"> * 如果枚举元素不赋值,则默认取值为下标
</span><span style="color: rgba(0, 128, 128, 1)">50</span> <span style="color: rgba(0, 128, 0, 1)"> * 如果某个元素取值为数字 n
</span><span style="color: rgba(0, 128, 128, 1)">51</span> <span style="color: rgba(0, 128, 0, 1)"> * 后面的元素如果不取值则默认为 n+1,以此类推
</span><span style="color: rgba(0, 128, 128, 1)">52</span> <span style="color: rgba(0, 128, 0, 1)"> * 如果某个元素取值为 string 类型
</span><span style="color: rgba(0, 128, 128, 1)">53</span> <span style="color: rgba(0, 128, 0, 1)"> * 后面的元素则必须取值,取值类型无要求
</span><span style="color: rgba(0, 128, 128, 1)">54</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">55</span> <span style="color: rgba(0, 0, 0, 1)">enum Color {
</span><span style="color: rgba(0, 128, 128, 1)">56</span> red, blue, black = 4, yellow, green = "green", white = 123
<span style="color: rgba(0, 128, 128, 1)">57</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">58</span>
<span style="color: rgba(0, 128, 128, 1)">59</span> let red: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.red;
</span><span style="color: rgba(0, 128, 128, 1)">60</span> let blue: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.blue;
</span><span style="color: rgba(0, 128, 128, 1)">61</span> let black: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.black;
</span><span style="color: rgba(0, 128, 128, 1)">62</span> let yellow: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.yellow;
</span><span style="color: rgba(0, 128, 128, 1)">63</span> let green: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.green;
</span><span style="color: rgba(0, 128, 128, 1)">64</span> let white: Color =<span style="color: rgba(0, 0, 0, 1)"> Color.white;
</span><span style="color: rgba(0, 128, 128, 1)">65</span> console.log(red, blue, black, yellow, green, white); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 0 1 4 5 "green" 123</span>
<span style="color: rgba(0, 128, 128, 1)">66</span>
<span style="color: rgba(0, 128, 128, 1)">67</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> undefined</span>
<span style="color: rgba(0, 128, 128, 1)">68</span> <span style="color: rgba(0, 0, 0, 1)">let un: undefined;
</span><span style="color: rgba(0, 128, 128, 1)">69</span> console.log(un); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> undefined</span>
<span style="color: rgba(0, 128, 128, 1)">70</span>
<span style="color: rgba(0, 128, 128, 1)">71</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 我们也可以通过 | 来赋值多种类元素</span>
<span style="color: rgba(0, 128, 128, 1)">72</span> let uns: number |<span style="color: rgba(0, 0, 0, 1)"> undefined;
</span><span style="color: rgba(0, 128, 128, 1)">73</span>
<span style="color: rgba(0, 128, 128, 1)">74</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> any 类型,可以为任意类型</span>
<span style="color: rgba(0, 128, 128, 1)">75</span> let an: any = 123<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">76</span> console.log(an); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 13</span>
<span style="color: rgba(0, 128, 128, 1)">77</span> an = "abc"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">78</span> console.log(an) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> abc</span></pre>
</div>
<p>在上面的代码中,我们演示了一下 Typescript 中的一些基本类型的使用,接下来我们再来看一下在函数中数据类型的应用。</p>
<p><span style="font-size: 14pt"><strong>Typescript 函数方法</strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果没有返回值,则在方法名后面加 :void</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">function</span> test(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> console.log("test"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> test(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> test</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果有返回值,则在方法名后面加 :返回值的类型</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> num(): number {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">return</span> 123<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> console.log(num()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 123</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> str(): string {
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 255, 1)">return</span> "abc"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> console.log(str()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "abc"</span>
<span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 定义传参</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 255, 1)">function</span> getData(name: string, age: number): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">23</span> console.log(`${name}--<span style="color: rgba(0, 0, 0, 1)">${age}`)
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">25</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> getData("张三", 18); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三--18</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getData("张三"); // 报错 Expected 2 arguments, but got 1.</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getData("张三","18"); // 报错 Argument of type '"18"' is not assignable to parameter of type 'number'.</span>
<span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 128, 0, 1)"> * 方法可选参数
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 128, 0, 1)"> * 在参数后面添加 ?
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 128, 0, 1)"> * 表示该参数为可选参数
</span><span style="color: rgba(0, 128, 128, 1)">34</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">function</span> getInfo(name: string, age?<span style="color: rgba(0, 0, 0, 1)">: number): string {
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (age) {
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 255, 1)">return</span> `${name}--<span style="color: rgba(0, 0, 0, 1)">${age}`
</span><span style="color: rgba(0, 128, 128, 1)">38</span> } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">39</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> `${name}`
</span><span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">41</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">42</span>
<span style="color: rgba(0, 128, 128, 1)">43</span> console.log(getInfo("张三", 18)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三--18</span>
<span style="color: rgba(0, 128, 128, 1)">44</span> console.log(getInfo("张三")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">45</span>
<span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">47</span> <span style="color: rgba(0, 128, 0, 1)"> * 方法默认参数
</span><span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 128, 0, 1)"> * 在参数后面直接赋值
</span><span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 128, 0, 1)"> * 表示该参数直接当做了被传入参数
</span><span style="color: rgba(0, 128, 128, 1)">50</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">51</span> <span style="color: rgba(0, 0, 255, 1)">function</span> getUser(name: string, age: number = 18<span style="color: rgba(0, 0, 0, 1)">): string {
</span><span style="color: rgba(0, 128, 128, 1)">52</span> <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (age) {
</span><span style="color: rgba(0, 128, 128, 1)">53</span> <span style="color: rgba(0, 0, 255, 1)">return</span> `${name}--<span style="color: rgba(0, 0, 0, 1)">${age}`
</span><span style="color: rgba(0, 128, 128, 1)">54</span> } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">55</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> `${name}`
</span><span style="color: rgba(0, 128, 128, 1)">56</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">57</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">58</span>
<span style="color: rgba(0, 128, 128, 1)">59</span> console.log(getUser("张三", 18)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三--18</span>
<span style="color: rgba(0, 128, 128, 1)">60</span> console.log(getUser("张三")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三--18</span>
<span style="color: rgba(0, 128, 128, 1)">61</span>
<span style="color: rgba(0, 128, 128, 1)">62</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">63</span> <span style="color: rgba(0, 128, 0, 1)"> * 剩余参数
</span><span style="color: rgba(0, 128, 128, 1)">64</span> <span style="color: rgba(0, 128, 0, 1)"> * 如果在传参过程中
</span><span style="color: rgba(0, 128, 128, 1)">65</span> <span style="color: rgba(0, 128, 0, 1)"> * 前面的参数已经给定
</span><span style="color: rgba(0, 128, 128, 1)">66</span> <span style="color: rgba(0, 128, 0, 1)"> * 在调用函数传参时会先将
</span><span style="color: rgba(0, 128, 128, 1)">67</span> <span style="color: rgba(0, 128, 0, 1)"> * 传入的参数作为指定参数
</span><span style="color: rgba(0, 128, 128, 1)">68</span> <span style="color: rgba(0, 128, 0, 1)"> * 剩余参数必须为最后一个参数传入
</span><span style="color: rgba(0, 128, 128, 1)">69</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">70</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 正常的传参</span>
<span style="color: rgba(0, 128, 128, 1)">71</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sum1(...arr: number[]): number {
</span><span style="color: rgba(0, 128, 128, 1)">72</span> let sum: number = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">73</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i < arr.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">74</span> sum +=<span style="color: rgba(0, 0, 0, 1)"> arr;
</span><span style="color: rgba(0, 128, 128, 1)">75</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">76</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sum;
</span><span style="color: rgba(0, 128, 128, 1)">77</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">78</span> console.log(sum1(1, 2, 3, 4)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 10</span>
<span style="color: rgba(0, 128, 128, 1)">79</span>
<span style="color: rgba(0, 128, 128, 1)">80</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> a 作为第一个参数,其余的为剩余参数,即 (a,剩余参数)</span>
<span style="color: rgba(0, 128, 128, 1)">81</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sum2(a: number, ...arr: number[]): number {
</span><span style="color: rgba(0, 128, 128, 1)">82</span> let sum: number = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">83</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i < arr.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">84</span> sum +=<span style="color: rgba(0, 0, 0, 1)"> arr;
</span><span style="color: rgba(0, 128, 128, 1)">85</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">86</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sum;
</span><span style="color: rgba(0, 128, 128, 1)">87</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">88</span> console.log(sum2(1, 2, 3, 4)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 10</span></pre>
</div>
<p> 在上面的代码中,我们实现了在 ts 中如何定义方法和如何进行方法传参,跟定义基本类型一样需要对方法进行有效的规定。</p>
<p>接下来我们再来看一下在 ts 中如何实现类和类的继承。</p>
<p><strong><span style="font-size: 14pt">Typescript 类</span></strong></p>
<p>在 ES5 中,我们是通过构造方法和原型链的方式进行继承的,在之前的文章中我们也讲过如何实现继承,传送门:https://www.cnblogs.com/weijiutao/p/12090916.html,Typescript 包含 ES6,所以本章着重讲解一下 ES6 中 class 关键字的类和继承。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在 ts 中定义类</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> getName(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> setName(name: string): string {
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">18</span> console.log("父类在工作"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">21</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> let p = <span style="color: rgba(0, 0, 255, 1)">new</span> Person("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">23</span> p.getName(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> p.setName("李四"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">25</span> p.getName(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 李四</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> p.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 父类在工作</span>
<span style="color: rgba(0, 128, 128, 1)">27</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在 ts 中实现继承</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 extends 继承了 Person 的属性和方法
</span><span style="color: rgba(0, 128, 128, 1)">31</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)">class Student extends Person {
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)"> super(name);
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">36</span>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 子类自己的方法</span>
<span style="color: rgba(0, 128, 128, 1)">38</span> run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">39</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span>.name + "在运动"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">41</span>
<span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 子类重写父类的方法</span>
<span style="color: rgba(0, 128, 128, 1)">43</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">44</span> console.log("子类在工作"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">45</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">46</span>
<span style="color: rgba(0, 128, 128, 1)">47</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">48</span>
<span style="color: rgba(0, 128, 128, 1)">49</span> let s = <span style="color: rgba(0, 0, 255, 1)">new</span> Student("王五"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">50</span> s.getName(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 王五</span>
<span style="color: rgba(0, 128, 128, 1)">51</span> s.run(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 王五在运动</span>
<span style="color: rgba(0, 128, 128, 1)">52</span> s.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 子类在工作</span></pre>
</div>
<pre>* 类里面的修饰符<br>* Typescript 里面定义属性的时候<br>* 给我们提供了三种修饰符<br>* public:公有类型,在类里面、子类、类外面都可以访问<br>* protected:保护类型,在类里面,子类里面可以访问,类外面无法访问<br>* private:私有类型,在类里面可以访问,子类,类外面无法访问<br>* 属性不加修饰符,默认为公有属性</pre>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 类里面的修饰符
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * Typescript 里面定义属性的时候
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 给我们提供了三种修饰符
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * public:公有类型,在类里面、子类、类外面都可以访问
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)"> * protected:保护类型,在类里面,子类里面可以访问,类外面无法访问
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 128, 0, 1)"> * private:私有类型,在类里面可以访问,子类,类外面无法访问
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)"> * 属性不加修饰符,默认为公有属性
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">13</span> public age: number = 18<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">14</span> protected sex: string = "男"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> private city: string = "北京"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在本类中访问 public 类型</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> getName(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">23</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">25</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在本类中访问 public 类型</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> getAge(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">28</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.age);
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">30</span>
<span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在本类中访问 protected 类型</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> getSex(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">33</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.sex);
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">35</span>
<span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在本类中访问 private 类型</span>
<span style="color: rgba(0, 128, 128, 1)">37</span> getCity(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">38</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.city);
</span><span style="color: rgba(0, 128, 128, 1)">39</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">40</span>
<span style="color: rgba(0, 128, 128, 1)">41</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">42</span>
<span style="color: rgba(0, 128, 128, 1)">43</span> let p = <span style="color: rgba(0, 0, 255, 1)">new</span> Person("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">44</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 外部访问 public 类型</span>
<span style="color: rgba(0, 128, 128, 1)">45</span> console.log(p.name); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 外部访问 public 类型</span>
<span style="color: rgba(0, 128, 128, 1)">47</span> console.log(p.age); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 18</span>
<span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 外部访问 protected 类型</span>
<span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(p.sex); // 报错 Property 'sex' is protected and only accessible within class 'Person' and its subclasses.</span>
<span style="color: rgba(0, 128, 128, 1)">50</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 外部访问 private 类型</span>
<span style="color: rgba(0, 128, 128, 1)">51</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(p.city); // 报错 Property 'city' is private and only accessible within class 'Person'.</span>
<span style="color: rgba(0, 128, 128, 1)">52</span>
<span style="color: rgba(0, 128, 128, 1)">53</span> <span style="color: rgba(0, 0, 0, 1)">class Student extends Person {
</span><span style="color: rgba(0, 128, 128, 1)">54</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">55</span> <span style="color: rgba(0, 0, 0, 1)"> super(name);
</span><span style="color: rgba(0, 128, 128, 1)">56</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">57</span>
<span style="color: rgba(0, 128, 128, 1)">58</span> getInfo(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">59</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在子类中访问 public 属性</span>
<span style="color: rgba(0, 128, 128, 1)">60</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
</span><span style="color: rgba(0, 128, 128, 1)">61</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在子类中访问 private 属性</span>
<span style="color: rgba(0, 128, 128, 1)">62</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.age);
</span><span style="color: rgba(0, 128, 128, 1)">63</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在子类中访问 protected 属性</span>
<span style="color: rgba(0, 128, 128, 1)">64</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.sex);
</span><span style="color: rgba(0, 128, 128, 1)">65</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在子类中访问 private 属性</span>
<span style="color: rgba(0, 128, 128, 1)">66</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(this.city) // 报错 Property 'city' is private and only accessible within class 'Person'.</span>
<span style="color: rgba(0, 128, 128, 1)">67</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">68</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">69</span>
<span style="color: rgba(0, 128, 128, 1)">70</span> let s = <span style="color: rgba(0, 0, 255, 1)">new</span> Student("王五"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">71</span> s.getInfo(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 王五 18 男</span></pre>
</div>
<p>在上面的代码中我们实现了一下 class 中的修饰符,接下来我们再来看一下 class 的静态属性、静态方法</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 static 关键字可以定义静态属性和静态方法
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 静态属性和静态方法直接通过 类. 来实现
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> static age: number = 18<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">15</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在运动`)
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 128, 0, 1)"> * 静态方法无法通过 this 调用类里面的属性
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 类. 调用
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> static work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">23</span> console.log("父类静态方法" +<span style="color: rgba(0, 0, 0, 1)"> Person.age)
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">26</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> let p = <span style="color: rgba(0, 0, 255, 1)">new</span> Person("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">28</span> p.run(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在运动</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> console.log(p.name); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">30</span>
<span style="color: rgba(0, 128, 128, 1)">31</span> console.log(Person.age); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 18</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> Person.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 父类静态方法18</span></pre>
</div>
<p>在上面的代码中我们实现了一下 class 中的静态属性、静态方法,接下来我们再来看一下 class 的多态</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 我们在定义类方法后
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 子类继承该类,并根据实际情况
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 来实现自己所需要的类方法
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> age: number;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">15</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在工作`)
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">class Student extends Person {
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> super(name);
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">25</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">27</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在学习`)
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">30</span> let s = <span style="color: rgba(0, 0, 255, 1)">new</span> Student("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">31</span> s.run(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在学习</span>
<span style="color: rgba(0, 128, 128, 1)">32</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)">class Teacher extends Person {
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 0, 1)"> super(name);
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">37</span>
<span style="color: rgba(0, 128, 128, 1)">38</span> run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">39</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在讲课`)
</span><span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">41</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">42</span> let t = <span style="color: rgba(0, 0, 255, 1)">new</span> Teacher("李四"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">43</span> t.run(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 李四在讲课</span></pre>
</div>
<p>在上面的代码中,我们定义了 Person 类并定义了一个 work 方法,然后 Student 和 Teacher 类分别继承了 Person,但是根据自己的角色重写了 work 方法,这就是一种多态。</p>
<p>接下来我们再来看一下 class 中的抽象类</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 抽象类是提供其他类继承的基类,不能被实例化
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * abstract 关键字定义抽象类和抽象方法
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 子抽象类中的抽象方法不能包含具体实现,必须在实现类中实现
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * 抽象类和抽象方法只是用来定义标准
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">abstract class Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)"> abstract work(): any;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 无法被实例化</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let p = new Person(); // 报错 error TS2511: Cannot create an instance of an abstract class.</span>
<span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">class Student extends Person {
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> super(name);
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)"> work(): any {
</span><span style="color: rgba(0, 128, 128, 1)">26</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在学习`)
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> let s = <span style="color: rgba(0, 0, 255, 1)">new</span> Student("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">31</span> s.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在学习</span></pre>
</div>
<p> </p>
<p><strong><span style="font-size: 14pt">Typescript 接口</span></strong></p>
<p>在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,几口是一种限制和规范的作用。接口定义了某一批类所需要遵循的规范,接口不关心这些类的内部状态数据,也不关心这些类里面方法的实现细节,它只规定这批类里面必须提供某些方法,提供这些方法的类就可以满足实际需要,Typescript 中的接口类似于 Java,同时还增加了更灵活的接口类型,包括属性、函数、数组类等。</p>
<p> 在日常生活中,我们会接触到很多类似接口的问题,比如 USB 接口,我们在电脑上插鼠标,键盘,U盘的时候不用去考虑它到底能不能插进去,只要型号对了就肯定能插进去,接口就相当于一个标准,你要想把鼠标插到我的电脑上,在出厂时就必须遵守该电脑定义的接口标准。</p>
<p>接下来我们就来看一下接口:</p>
<p>1、属性和类接口</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">interface FullName {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)"> firstName:string,
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)"> lastName:string,
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> sayHi: ()=><span style="color: rgba(0, 0, 0, 1)">string
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> let person:FullName =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> firstName:"张"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> lastName:"三"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">10</span> sayHi: ():string =>{<span style="color: rgba(0, 0, 255, 1)">return</span> "hell world"<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> console.log(person.firstName); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> console.log(person.lastName); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 三</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> console.log(person.sayHi()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> hello world</span></pre>
</div>
<p>在上面的代码中,我们通过 interface 编写了一个 FullName 的接口,然后定义了一个 person 的变量来实现这个接口,那么我们就可以使用该接口里面的属性了。</p>
<p> 2、函数类型接口</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对方法传入的参数以及返回值进行约束</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">interface encrypted {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)"> (key: string, value: string): string
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> key 和 value 必须符合 encrypted 接口的 string 类型约束</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> let getData: encrypted = (key: string, value: string) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">return</span> `${key}--<span style="color: rgba(0, 0, 0, 1)">${value}`;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 错误写法</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let getData:encrypted = (key:number,value:string)=>{</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return `${key}--${value}`;</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> };</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> console.log(getData("name", "张三")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> name--张三</span></pre>
</div>
<p>3、数组类型接口</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">interface nameArray {
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)"> :string
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> let list:nameArray = ["张三","李四"<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let list:namelist = ["张三","李四",123]; // 错误元素 123 不是 string 类型</span></pre>
</div>
<p>4、接口的继承</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 implements 来实现接口的继承
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 同时接口内的属性和方法在子类中必须重新定义
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 可以实现多继承,class 子类 implements 接口1, 接口2{ }
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">interface Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> name: string,
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> work: () => <span style="color: rgba(0, 0, 255, 1)">void</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">class Student implements Person {
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">20</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在学习`)
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> let s = <span style="color: rgba(0, 0, 255, 1)">new</span> Student("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">25</span> s.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在学习</span></pre>
</div>
<p>5、接口的扩展</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 extends 来实现接口的扩展
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 在实现接口的时候,接口的扩展接口也必须重新定义
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">interface Animals {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> name: string,
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">interface Person extends Animals {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> age: number,
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> let person:Person =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">15</span> name:"张三"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">16</span> age: 18
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">18</span> console.log(person); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {name: "张三", age: 18}</span></pre>
</div>
<p> </p>
<p><span style="font-size: 14pt"><strong>Typescript 泛型</strong></span></p>
<p>在软件工程中,我们不仅要创建一致的定义良好的 API,同时也要考虑可重用性,组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。</p>
<p>在 C# 和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据,这样用户就可以有自己的数据类型来使用组件。</p>
<p> 通俗理解,泛型就是解决函数、类、接口 的复用性,以及对不特定数据类型的支持。</p>
<p>1、泛型函数</p>
<p>现在需要写一个方法实现,我们传入的参数和返回的参数保持一致,并且参数必须为 string 或者 number,按照正常的思维我们代码应该是这样:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getData1(value: string): string {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getData2(value: number): number {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 string 类型</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> getData1("abc"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 number 类型</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> getData2(123);</pre>
</div>
<p>在上面的代码中,我们需要定义两个不同的方法来分别实现 string 和 number 类型数据的返回,这样会造成大量重复代码,当然我们可以将返回类型变为 any 类型来解决,如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getData(value: any): any {
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value;
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 string 类型</span>
<span style="color: rgba(0, 128, 128, 1)">6</span> getData("abc"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 number 类型</span>
<span style="color: rgba(0, 128, 128, 1)">8</span> getData(123);</pre>
</div>
<p>使用 any 类型可以解决我们的问题,但是其实是放弃了类型检验,和普通 js 就没有什么区别了。</p>
<p>接下来我们来看一下泛型是如何解决该问题的:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 定义泛型类型 T
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 我们需要 T 是什么类型
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 直接定义 T 的类型即可
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * @param value
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">function</span> getData<T><span style="color: rgba(0, 0, 0, 1)">(value: T): T {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 string 类型</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> getData<string>("abc"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回 number 类型</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> getData<number>(123<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">15</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 错误写法</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getData<string>(456); // 报错 rgument of type '456' is not assignable to parameter of type 'string'.</span></pre>
</div>
<p>在上面的代码中,我们通过 T 来定义方法的泛型,这样方法在传入时需要先定义参数的类型,然后定义返回数据类型,这样就实现了上面的问题。</p>
<p>2、泛型类</p>
<p>现在有这样一个问题,我们要定义一个类,该类中 toString 方法返回值为一个二维坐标系上的某个点,按照之前我们讲的类的内容,可以写出如下代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">class Point {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)"> x: number;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)"> y: number;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(x: number, y: number) {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.x =<span style="color: rgba(0, 0, 0, 1)"> x;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.y =<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> toString() {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">return</span> "(" + <span style="color: rgba(0, 0, 255, 1)">this</span>.x + "," + <span style="color: rgba(0, 0, 255, 1)">this</span>.y + ")"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> let p = <span style="color: rgba(0, 0, 255, 1)">new</span> Point(1, 2<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 坐标系点 (1,2)</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> console.log(p.toString()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (1,2)</span></pre>
</div>
<p>上面的代码可以实现我们想要的功能,但是现在又有新需求,坐标系上的点可以为 string 类型的数据,入(一,二),而我们在定义传入 x,y 时候已经定义了它传入的类型必须是 number 类型,如果向函数泛型那样定义 any 类型的话其实就失去了类型校验,跟普通的 js 没有什么区别了,这时候就需要泛型来解决了,如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * Point 类的泛型 T
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * Point 需要传入什么参数类型
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 就让 T 是什么类型即可
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> class Point<T><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> x: T;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> y: T;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(x: T, y: T) {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.x =<span style="color: rgba(0, 0, 0, 1)"> x;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.y =<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)"> toString() {
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 255, 1)">return</span> "(" + <span style="color: rgba(0, 0, 255, 1)">this</span>.x + "," + <span style="color: rgba(0, 0, 255, 1)">this</span>.y + ")"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> let p1 = <span style="color: rgba(0, 0, 255, 1)">new</span> Point<number>(1, 2<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 坐标系点 (1,2)</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> console.log(p1.toString()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (1,2)</span>
<span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> let p2 = <span style="color: rgba(0, 0, 255, 1)">new</span> Point<string>("一", "二"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 坐标系点 (一,二)</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> console.log(p1.toString()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (一,二)</span></pre>
</div>
<p>在上面的代码中,我们通过 T 实现了 Point 类型的泛型,Point 需要传入什么类型的参数,我们就将 T 定义成什么类型的数据即可。</p>
<p>3、泛型接口</p>
<p>还是上面的问题,不过这次我们是将 Point 写成接口的形式,如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">interface Point {
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)"> (x: number, y: number): string
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> let getPoint: Point = (x, y): string => "(" + x + "," + y + ")"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">6</span>
<span style="color: rgba(0, 128, 128, 1)">7</span> console.log(getPoint(1, 2)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (1,2)</span></pre>
</div>
<p>在上面的代码中,我们将 x 和 y 定义为 number 类型,这样在传入参数时就只能是 number 类型了,按照上面泛型函数和泛型类的方法,我们将 number 变为 T,如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> interface Point<T><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)"> (x: T, y: T): string
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> let getPoint1: Point<number> = (x, y): string => "(" + x + "," + y + ")"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 坐标系点 (1,2)</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> console.log(getPoint1(1, 2)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (1,2)</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> let getPoint2: Point<string> = (x, y): string => "(" + x + "," + y + ")"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 坐标系点 (一,二)</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> console.log(getPoint2("一", "二")); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> (一,二)</span></pre>
</div>
<p>通过 T 我们将 Point 接口传入的参数 x,y 进行泛型,这样我们就可以根据自己的需求传入我们想要的参数类型了。</p>
<h1>TypeScript 模块</h1>
<p>TypeScript 模块的设计理念是可以更换的组织代码。</p>
<p>模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。</p>
<p>两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。</p>
<p>模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。 大家最熟知的JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js。</p>
<p>此外还有有 SystemJs 和 Webpack。</p>
<p>模块导出使用关键字 <span class="marked">export 关键字,</span>要在另外一个文件使用该模块就需要使用 <span class="marked">import 关键字来导入。</span></p>
<p><span class="marked">接下来我们就来实现一下:</span></p>
<p><span class="marked"><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191225134141194-247829393.png" alt=""></span></p>
<p> </p>
<p> 在上图中我们通过 module.ts 中 export 关键字导出我们封装好的属性和方法,在 test.ts 中我们就可以使用 import 关键字来导入我们想要的属性和放大了。</p>
<p>我们也可以通过 export default 来导出模块,如下</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1345718/201912/1345718-20191225134840544-1697219724.png" alt=""></p>
<p> </p>
<p> 但是 export default 在模块导出只能引用一次,导入时也不能使用 { },而是直接导入模块即可。</p>
<p> </p>
<p><strong><span style="font-size: 14pt">Typescript 命名空间</span></strong></p>
在代码量较大的情况下,为了避免各种命名冲突,可将相似功能的函数,类,接口等放置到命名空间内。同 Java 的包,.net 的命名空间一样,Typescript 的命名空间可以将代码包括起来,只对外暴露需要在外部访问的对象,命名空间内的对象通过 export 导出。</div>
<div>举个栗子:假如现在有 A 和 B 两个开发者同时定义了一个 Person 的类,那么这两个类就会引起冲突,为了避免冲突,就不得不再引入其他标识来辨别这两个 Person,空间命名就是为了解决该问题,如下:</div>
<div> </div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 通过 namespace 来定义命名空间
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> *分别定义了 A 和 B 两个命名空间
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 我们可以根据需求来调用 A 或 B 里面类和方法
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">namespace A {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)"> interface Person {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)"> name: string,
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> export class Student implements Person {
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">15</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)"> work() {
</span><span style="color: rgba(0, 128, 128, 1)">21</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在学习`)
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">25</span>
<span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)">namespace B {
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)"> interface Person {
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)"> name: string,
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> work(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">32</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)"> export class Student implements Person {
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">35</span>
<span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)"> constructor(name: string) {
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">39</span>
<span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)"> work() {
</span><span style="color: rgba(0, 128, 128, 1)">41</span> console.log(`${<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}在写作业`)
</span><span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">43</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">44</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">45</span>
<span style="color: rgba(0, 128, 128, 1)">46</span> let a = <span style="color: rgba(0, 0, 255, 1)">new</span> A.Student("张三"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">47</span> a.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在学习</span>
<span style="color: rgba(0, 128, 128, 1)">48</span> let b = <span style="color: rgba(0, 0, 255, 1)">new</span> B.Student("李四"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">49</span> b.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 李四在写作业</span></pre>
</div>
<p>空间命名用起来很简单,只需要通过 namespace 关键字来命名空间即可。</p>
<p> </p>
</div>
<div><strong><span style="font-size: 14pt">Typescript 装饰器</span></strong></div>
<div>装饰器是一种特殊类型的生命,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。通俗的讲装饰器就是一个方法,可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能。</div>
<div>常见的装饰器有:类装饰器,属性装饰器,方法装饰器,参数装饰器。</div>
<div>装饰器的写法有:普通装饰器(无法传参),装饰器工厂(可传参)</div>
<div>装饰器是过去几年中 js 最大的成就之一,也是 ES7 的标准特性之一。</div>
<div> </div>
<div>1、类装饰器:</div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 类小黄使其在声明之前被声明(紧靠着类声明)
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 类装饰器应用于类构造函数
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 可以用来监视,修改或替换类定义
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> log(params: any) {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> console.log(params); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ƒ Person() {}</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> params.prototype.name = "动态属性"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> params.prototype.func = () =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> console.log("动态方法"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">@log
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> let p: any = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
</span><span style="color: rgba(0, 128, 128, 1)">20</span> console.log(p.name); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 动态属性</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> p.func(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 动态方法</span></pre>
</div>
<p>在上面的代码中,我们通过 @log 的形式来定义装饰器,在 log 方法中传入一个 params 的参数,通过打印我们发现它就是 Person 方法了,那么我们就可以通过原型链 prototype 的形式添加属性和方法了。</p>
<p>上面@log 并没有传参,接下来我们看一下在调用装饰器的时候传入我们想要的参数:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 在 log 方法中,我们通过 return 方式
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 将该方法返回,那就跟无参装饰器一样了
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 这样我们就可以在 log 方法中传参了,如 params
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> log(params: string) {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (target: any) {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> console.log(params); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> console.log(target); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> f Person() {}</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> target.prototype.name =<span style="color: rgba(0, 0, 0, 1)"> params;
</span><span style="color: rgba(0, 128, 128, 1)">11</span> target.prototype.work = <span style="color: rgba(0, 0, 255, 1)">function</span> (): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)"> console.log(`${params}在工作`)
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> @log("张三"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">21</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> let p: any = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
</span><span style="color: rgba(0, 128, 128, 1)">23</span> console.log(p.name); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> p.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在工作</span></pre>
</div>
<p> </p>
</div>
<div>2、属性装饰器</div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 属性装饰器表达式会在运行时当作函数被调用
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 传入下列 2 个参数
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * 2、成员的名字
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> log(param: any) {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span> (target: any, key: string) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 分别传入 2 个参数</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> console.log(param); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> console.log(target); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {constructor: ƒ}</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> console.log(key); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> name</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> target =<span style="color: rgba(0, 0, 0, 1)"> param;
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">15</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">18</span> @log("张三"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)"> constructor() {
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> getName(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">25</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">28</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> let p: any = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
</span><span style="color: rgba(0, 128, 128, 1)">30</span> console.log(p.name); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">31</span> p.getName(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span></pre>
</div>
</div>
<div>
<p>在上面的代码中,我们在 name:string 上面添加了 @log 的装饰器,这就是属性装饰器,同时我们对装饰器进行了传参“张三”,我们将 log 方法返回,通过打印发现返回的方法的第一个参数 target 为 constructor 构造器,第二个参数为 name,那我们就可以根据 target 的形式对 name 属性进行赋值了。</p>
</div>
<div> 3、方法装饰器</div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 方法装饰器会被应用到方法的属性描述符上
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 用来修改,监视和替换方法定义
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 方法装饰器在运行时传入下列三个参数
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * 1、对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)"> * 2、成员的名字
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 128, 0, 1)"> * 3、成员的属性描述符
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> log(param: any) {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span> (target: any, key: any, description: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 分别传入三个参数</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> console.log(param); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> console.log(target); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {getName: ƒ, constructor: ƒ}</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> console.log(key); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getName</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> console.log(description); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {writable: true, enumerable: true, configurable: true, value: ƒ}</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> console.log(description.value); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ƒ () {console.log(this.name) }</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> target.age = 20; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加属性</span>
<span style="color: rgba(0, 128, 128, 1)">17</span> target.work = () => console.log(`${param}在工作`); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加方法</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 修改 getName 方法</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> description.value = ():<span style="color: rgba(0, 0, 255, 1)">void</span> => console.log(`${param}---<span style="color: rgba(0, 0, 0, 1)">我是被修改的 getName 方法`);
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">22</span>
<span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)"> name: string;
</span><span style="color: rgba(0, 128, 128, 1)">26</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)"> constructor() {
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> @log("张三"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">31</span> getName(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">32</span> console.log(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">35</span>
<span style="color: rgba(0, 128, 128, 1)">36</span> let p: any = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
</span><span style="color: rgba(0, 128, 128, 1)">37</span> console.log(p.age); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 20</span>
<span style="color: rgba(0, 128, 128, 1)">38</span> p.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三在工作</span>
<span style="color: rgba(0, 128, 128, 1)">39</span> p.getName(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三---我是被修改的 getName 方法</span></pre>
</div>
<p>4、方法参数装饰器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> * 方法参数装饰器会在运行时当中函数被调用
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * 可以使用参数装饰器为类的原型增加一些元素数据
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * 传入下列 3 个参数
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)"> * 1、对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)"> * 2、方法的名字
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 128, 0, 1)"> * 3、参数在函数参数列表中的索引
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> log(param: any) {
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span> (target: any, methodName: any, index: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 分别传入三个参数</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> console.log(param); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> name</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> console.log(target); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {getData: ƒ, constructor: ƒ}</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> console.log(methodName); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getData</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> console.log(index); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 0</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> target.age = 18<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">16</span> target.work = (): <span style="color: rgba(0, 0, 255, 1)">void</span> =><span style="color: rgba(0, 0, 0, 1)"> console.log(`我在工作`)
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">class Person {
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)"> constructor() {
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">24</span>
<span style="color: rgba(0, 128, 128, 1)">25</span> getData(@log("name") name: string): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)"> console.log(name);
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> let p: any = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
</span><span style="color: rgba(0, 128, 128, 1)">31</span> p.getData("张三"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 张三</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> console.log(p.age); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 18</span>
<span style="color: rgba(0, 128, 128, 1)">33</span> p.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 我在工作</span></pre>
</div>
<p>方法参数装饰器跟其他装饰器不同的是需要将 @log 写在方法的参数内,比较怪,一般情况下方法装饰器就能解决方法参数装饰器所实现的功能,所以一般我们使用方法参数器即可。</p>
<p>装饰器的执行顺序:属性装饰器>方法装饰器>方法参数装饰器>类装饰器,如果有多个相同装饰器,则先执行后面的装饰器。</p>
</div>
<div>
<p> </p>
</div>
<div>
<p>以上就是本人目前学习 Typescript 的一些整理归纳,好记性不如烂笔头,谨以此记,与君共勉!</p>
<p> </p>
</div><br><br>
来源:https://www.cnblogs.com/weijiutao/p/12083551.html
頁:
[1]