-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1251921997.html
More file actions
1380 lines (1023 loc) · 120 KB
/
Copy path1251921997.html
File metadata and controls
1380 lines (1023 loc) · 120 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en" data-default-color-scheme="auto">
<head>
<meta charset="UTF-8">
<link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
<link rel="icon" href="/img/fluid.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="theme-color" content="#2f4154">
<meta name="author" content="FangZhou">
<meta name="keywords" content="typescript,javascript,ts,js,web">
<meta name="description" content="TypeScript类型系统学习笔记,从基础到高级类型应用">
<meta property="og:type" content="article">
<meta property="og:title" content="TypeScript学习笔记">
<meta property="og:url" content="http://arkpln.github.io/1251921997.html">
<meta property="og:site_name" content="Ark的技术博客">
<meta property="og:description" content="TypeScript类型系统学习笔记,从基础到高级类型应用">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2025-08-02T05:14:31.000Z">
<meta property="article:modified_time" content="2026-02-22T13:36:56.822Z">
<meta property="article:author" content="FangZhou">
<meta property="article:tag" content="frontend">
<meta property="article:tag" content="typescript">
<meta property="article:tag" content="javascript">
<meta property="article:tag" content="typing">
<meta name="twitter:card" content="summary_large_image">
<title>TypeScript学习笔记 - Ark的技术博客</title>
<link rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css">
<link rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css">
<!-- 主题依赖的图标库,不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_1749284_5i9bdhy70f8.css">
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_1736178_k526ubmyhba.css">
<link rel="stylesheet" href="/css/main.css">
<link id="highlight-css" rel="stylesheet" href="/css/highlight.css">
<link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css">
<script id="fluid-configs">
var Fluid = window.Fluid || {};
Fluid.ctx = Object.assign({}, Fluid.ctx)
var CONFIG = {"hostname":"arkpln.github.io","root":"/","version":"1.9.8","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"follow_dnt":true,"baidu":null,"google":{"measurement_id":null},"tencent":{"sid":null,"cid":null},"leancloud":{"app_id":"mEwkD7geCX7RWNO8srhDE2oP-gzGzoHsz","app_key":"4EF76hyiVA1QILHZThVbfoat","server_url":"https://mewkd7ge.lc-cn-n1-shared.com","path":"window.location.pathname","ignore_local":false},"umami":{"src":null,"website_id":null,"domains":null,"start_time":"2024-01-01T00:00:00.000Z","token":null,"api_server":null}},"search_path":"/local-search.xml","include_content_in_search":true};
if (CONFIG.web_analytics.follow_dnt) {
var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
}
</script>
<script src="/js/utils.js"></script>
<script src="/js/color-schema.js"></script>
<meta name="google-site-verification" content="5KfTZvtlydmBIzY97rVo-caP5jljAfmD3Qs3sBzY2Go"><style>ins.adsbygoogle[data-ad-status="unfilled"] { display: none !important; }</style>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<header>
<div class="header-inner" style="height: 70vh;">
<nav id="navbar" class="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar">
<div class="container">
<a class="navbar-brand" href="/">
<strong>Ark的技术博客</strong>
</a>
<button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<div class="animated-icon"><span></span><span></span><span></span></div>
</button>
<!-- Collapsible content -->
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto text-center">
<li class="nav-item">
<a class="nav-link" href="/" target="_self">
<i class="iconfont icon-home-fill"></i>
<span>快乐老家</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/archives/" target="_self">
<i class="iconfont icon-archive-fill"></i>
<span>笔岚档案</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/categories/" target="_self">
<i class="iconfont icon-category-fill"></i>
<span>文以类聚</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/tags/" target="_self">
<i class="iconfont icon-tags-fill"></i>
<span>按标签阅览</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/about/" target="_self">
<i class="iconfont icon-user-fill"></i>
<span>联系我</span>
</a>
</li>
<li class="nav-item" id="search-btn">
<a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
<i class="iconfont icon-search"></i>
</a>
</li>
<li class="nav-item" id="color-toggle-btn">
<a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
<i class="iconfont icon-dark" id="color-toggle-icon"></i>
</a>
</li>
</ul>
</div>
</div>
</nav>
<div id="banner" class="banner" parallax="true" style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
<div class="full-bg-img">
<div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
<div class="banner-text text-center fade-in-up">
<div class="h2">
<span id="subtitle" data-typed-text="TypeScript学习笔记"></span>
</div>
<div class="mt-3">
<span class="post-meta">
<i class="iconfont icon-date-fill" aria-hidden="true"></i>
<time datetime="2025-08-02 13:14" pubdate>
August 2, 2025 pm
</time>
</span>
</div>
<div class="mt-1">
<span class="post-meta mr-2">
<i class="iconfont icon-chart"></i>
17k words
</span>
<span class="post-meta mr-2">
<i class="iconfont icon-clock-fill"></i>
140 mins
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<main>
<div class="container-fluid nopadding-x">
<div class="row nomargin-x">
<div class="side-col d-none d-lg-block col-lg-2">
<aside class="sidebar d-none d-xl-block" style="margin-right:-1rem;z-index:-1"><ins class="adsbygoogle" style="display:flex;justify-content:center;min-width:160px;max-width:300px;width:100%;height:600px;position:sticky;top:2rem" data-ad-client="ca-pub-3240358922862141" data-ad-slot="6522434837"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></aside>
</div>
<div class="col-lg-8 nopadding-x-md">
<div class="container nopadding-x-md" id="board-ctn">
<div id="board">
<article class="post-content mx-auto">
<h1 id="seo-header">TypeScript学习笔记</h1>
<div class="markdown-body">
<h1 id="TypeScript学习笔记"><a href="#TypeScript学习笔记" class="headerlink" title="TypeScript学习笔记"></a>TypeScript学习笔记</h1><h2 id="一-TypeScript简介"><a href="#一-TypeScript简介" class="headerlink" title="一.TypeScript简介"></a>一.TypeScript简介</h2><p>TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(<a target="_blank" rel="external nofollow noopener noreferrer" href="https://www.runoob.com/w3cnote/es6-tutorial.html">ES6 教程</a>)。</p>
<p>TypeScript 由微软开发的自由和开源的编程语言,在 JavaScript 的基础上增加了静态类型检查的超集,添加了诸多现代开发特性。</p>
<p>TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。</p>
<h2 id="二-为什么需要TypeScript"><a href="#二-为什么需要TypeScript" class="headerlink" title="二.为什么需要TypeScript"></a>二.为什么需要TypeScript</h2><ol>
<li><p>数据类型问题</p>
</li>
<li><p>逻辑漏洞问题</p>
</li>
<li><p>访问不存在的属性</p>
</li>
<li><p>拼写错误</p>
</li>
</ol>
<h2 id="三-编译TypeScript"><a href="#三-编译TypeScript" class="headerlink" title="三.编译TypeScript"></a>三.编译TypeScript</h2><h3 id="1-命令行编译"><a href="#1-命令行编译" class="headerlink" title="1.命令行编译"></a>1.命令行编译</h3><ol>
<li><p>创建<code>.ts</code>文件</p>
</li>
<li><p>全局安装<code>TypeScript</code>(此处为使用的包管理工具是pnpm,pnpm较npm速度有显著提升且节约空间)</p>
</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm add -g typescript<br></code></pre></td></tr></table></figure>
<ol start="3">
<li>使用<code>tsc</code>命令编译</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm exec tsc demo.ts<br></code></pre></td></tr></table></figure>
<h3 id="2-自动化编译"><a href="#2-自动化编译" class="headerlink" title="2.自动化编译"></a>2.自动化编译</h3><ol>
<li>全局安装</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm init<br>pnpm i ts-node <br>pnpm i typescript <br>pnpm i tsc <br></code></pre></td></tr></table></figure>
<ol start="2">
<li>创建编译控制文件</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm exec tsc --init<br></code></pre></td></tr></table></figure>
<ol start="3">
<li>监视目录中<code>.ts</code>的文件变化</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm exec tsc --w<br></code></pre></td></tr></table></figure>
<h3 id="3-Code-Runner插件-适用VSCode等平台"><a href="#3-Code-Runner插件-适用VSCode等平台" class="headerlink" title="3.Code Runner插件(适用VSCode等平台)"></a>3.Code Runner插件(适用VSCode等平台)</h3><ol>
<li>在VS Code下安装<code>Code Runner</code>插件</li>
<li>进入插件设置,勾选<code>File Directory As Cwd</code></li>
<li>创建<code>.ts</code>文件</li>
<li>在目录所在终端下依次执行</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs shell">pnpm init<br>pnpm add typescript<br>pnpm exec tsc --init<br></code></pre></td></tr></table></figure>
<ol start="5">
<li>点击右上角执行按钮</li>
</ol>
<h2 id="四-类型声明"><a href="#四-类型声明" class="headerlink" title="四.类型声明"></a>四.类型声明</h2><p>使用 <code>:</code>来对变量或函数形参,进行类型声明。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span> = <span class="hljs-string">"StringType"</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">add</span> = (<span class="hljs-params"><span class="hljs-attr">numOne</span>:<span class="hljs-built_in">number</span>,<span class="hljs-attr">numTwo</span>:<span class="hljs-built_in">number</span></span>) =>{<br> <span class="hljs-keyword">return</span> numOne + numTwo<br>}<br><br><span class="hljs-keyword">const</span> res = <span class="hljs-title function_">add</span>(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>)<br></code></pre></td></tr></table></figure>
<p><code>:</code>也可以给变量附加上字面量类型,但不常见。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">s</span>:<span class="hljs-string">'TS你好'</span><br></code></pre></td></tr></table></figure>
<h2 id="五-类型推断"><a href="#五-类型推断" class="headerlink" title="五.类型推断"></a>五.类型推断</h2><p>TypeScript 能够自动推断变量的类型。比如当你声明一个变量并赋值时,TypeScript 会根据赋值来推断这个变量的类型,不需要每次都显式声明类型。</p>
<h2 id="六-类型总览"><a href="#六-类型总览" class="headerlink" title="六.类型总览"></a>六.类型总览</h2><h3 id="JavaScript数据类型"><a href="#JavaScript数据类型" class="headerlink" title="JavaScript数据类型"></a>JavaScript数据类型</h3><h4 id="基本数据类型"><a href="#基本数据类型" class="headerlink" title="基本数据类型"></a>基本数据类型</h4><table>
<thead>
<tr>
<th>数据类型</th>
<th>描述</th>
<th>示例</th>
<th>特点</th>
</tr>
</thead>
<tbody><tr>
<td><code>Number</code></td>
<td>数字类型,包括整数和浮点数</td>
<td><code>42</code>, <code>3.14</code></td>
<td>所有数字都是64位浮点数存储,包含特殊值<code>Infinity</code>、<code>-Infinity</code>和<code>NaN</code></td>
</tr>
<tr>
<td><code>String</code></td>
<td>字符串类型,表示文本数据</td>
<td><code>"hello"</code>, <code>'world'</code></td>
<td>不可变,可以使用单引号或双引号表示</td>
</tr>
<tr>
<td><code>Boolean</code></td>
<td>布尔类型,表示逻辑值</td>
<td><code>true</code>, <code>false</code></td>
<td>只有两个值:<code>true</code>和<code>false</code></td>
</tr>
<tr>
<td><code>Undefined</code></td>
<td>表示未定义的值</td>
<td><code>undefined</code></td>
<td>变量声明但未赋值时的默认值</td>
</tr>
<tr>
<td><code>Null</code></td>
<td>表示空值</td>
<td><code>null</code></td>
<td>表示有意设置的空值</td>
</tr>
<tr>
<td><code>Symbol</code></td>
<td>ES6新增,表示唯一的、不可变的值</td>
<td><code>Symbol('desc')</code></td>
<td>主要用于对象属性的唯一标识符</td>
</tr>
<tr>
<td><code>BigInt</code></td>
<td>ES2020新增,表示任意精度的整数</td>
<td><code>123n</code></td>
<td>用于表示大于2^53-1的整数</td>
</tr>
</tbody></table>
<h4 id="引用数据类型"><a href="#引用数据类型" class="headerlink" title="引用数据类型"></a>引用数据类型</h4><table>
<thead>
<tr>
<th>数据类型</th>
<th>描述</th>
<th>示例</th>
</tr>
</thead>
<tbody><tr>
<td><code>Object</code></td>
<td>对象类型,用于存储键值集合</td>
<td><code>{name: 'John'}</code></td>
</tr>
<tr>
<td><code>Array</code></td>
<td>数组类型,特殊类型的对象</td>
<td><code>[1, 2, 3]</code></td>
</tr>
<tr>
<td><code>Function</code></td>
<td>函数类型,也是对象的一种</td>
<td><code>function() {}</code></td>
</tr>
<tr>
<td><code>Date</code></td>
<td>日期类型</td>
<td><code>new Date()</code></td>
</tr>
<tr>
<td><code>RegExp</code></td>
<td>正则表达式类型</td>
<td><code>/pattern/flags</code></td>
</tr>
<tr>
<td>…其他对象</td>
<td>包括<code>Map</code>, <code>Set</code>, <code>WeakMap</code>, <code>WeakSet</code>等</td>
<td><code>new Map()</code></td>
</tr>
</tbody></table>
<h4 id="特殊情况"><a href="#特殊情况" class="headerlink" title="特殊情况"></a>特殊情况</h4><h5 id="1-Undefined"><a href="#1-Undefined" class="headerlink" title="1. Undefined"></a>1. <code>Undefined</code></h5><ul>
<li><p><strong>特点</strong>:</p>
<ul>
<li><p>表示变量已声明但未赋值时的默认值</p>
</li>
<li><p>类型为<code>"undefined"</code></p>
</li>
<li><p>使用<code>typeof</code>检测未声明变量也会返回<code>"undefined"</code></p>
</li>
<li><p>通常表示”缺少值”,即应该有值但未定义</p>
</li>
<li><p>不建议手动赋值为<code>undefined</code>,应使用<code>null</code>表示有意空值</p>
</li>
</ul>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">let</span> x;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x); <span class="hljs-comment">// undefined</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> x); <span class="hljs-comment">// "undefined"</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> y); <span class="hljs-comment">// "undefined" (y未声明)</span><br></code></pre></td></tr></table></figure>
<h5 id="2-Null"><a href="#2-Null" class="headerlink" title="2. Null"></a>2. <code>Null</code></h5><ul>
<li><p><strong>特点</strong>:</p>
<ul>
<li><p>表示”无”的对象,即该处不应该有值</p>
</li>
<li><p>类型为<code>"object"</code>(这是历史遗留bug)</p>
</li>
<li><p>使用<code>=== null</code>可以准确检测<code>null</code>值</p>
</li>
<li><p>通常用于主动释放对象引用</p>
</li>
<li><p>是原型链的终点(<code>Object.prototype.__proto__ === null</code>)</p>
</li>
</ul>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">let</span> x = <span class="hljs-literal">null</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> x); <span class="hljs-comment">// "object" (注意这是历史遗留问题)</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x === <span class="hljs-literal">null</span>); <span class="hljs-comment">// true</span><br></code></pre></td></tr></table></figure>
<h5 id="undefined-vs-null"><a href="#undefined-vs-null" class="headerlink" title="undefined vs null"></a><code>undefined</code> vs <code>null</code></h5><table>
<thead>
<tr>
<th>比较点</th>
<th><code>undefined</code></th>
<th><code>null</code></th>
</tr>
</thead>
<tbody><tr>
<td>含义</td>
<td>表示未定义</td>
<td>表示空值</td>
</tr>
<tr>
<td>类型</td>
<td><code>"undefined"</code></td>
<td><code>"object"</code></td>
</tr>
<tr>
<td>产生方式</td>
<td>变量未赋值时的默认值</td>
<td>必须显式赋值</td>
</tr>
<tr>
<td>转换为数值</td>
<td><code>NaN</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td>使用场景</td>
<td>表示”缺少值”</td>
<td>表示”无对象”</td>
</tr>
<tr>
<td>严格相等比较</td>
<td><code>undefined === undefined</code> → <code>true</code></td>
<td><code>null === null</code> → <code>true</code></td>
</tr>
</tbody></table>
<h4 id="类型检测方法"><a href="#类型检测方法" class="headerlink" title="类型检测方法"></a>类型检测方法</h4><ol>
<li><p><code>typeof</code> 操作符</p>
<ul>
<li><p>返回类型字符串</p>
</li>
<li><p><code>null</code>返回<code>"object"</code>(历史遗留问题,底层是32为)</p>
</li>
<li><p>函数返回<code>"function"</code></p>
</li>
</ul>
</li>
<li><p><code>instanceof</code> 操作符</p>
<ul>
<li>检测对象是否属于特定构造函数</li>
</ul>
</li>
<li><p><code>Object.prototype.toString.call()</code></p>
<ul>
<li>最准确的类型检测方法</li>
</ul>
</li>
</ol>
<h3 id="TypeScript数据类型"><a href="#TypeScript数据类型" class="headerlink" title="TypeScript数据类型"></a>TypeScript数据类型</h3><p>包含全部JavaScript数据类型</p>
<h4 id="新增基本数据类型"><a href="#新增基本数据类型" class="headerlink" title="新增基本数据类型"></a>新增基本数据类型</h4><table>
<thead>
<tr>
<th>类型</th>
<th>描述</th>
<th>示例</th>
<th>特点</th>
</tr>
</thead>
<tbody><tr>
<td><code>any</code></td>
<td>任意类型,跳过类型检查</td>
<td><code>let x: any = 'hello';</code></td>
<td>1. 可以赋值为任何值<br>2. 可以访问任何属性/方法<br>3. 尽量避免使用</td>
</tr>
<tr>
<td><code>unknown</code></td>
<td>类型安全的<code>any</code></td>
<td><code>let y: unknown = 4;</code></td>
<td>1. 可以赋值为任何值<br>2. 不能直接操作,需先类型断言或收窄</td>
</tr>
<tr>
<td><code>never</code></td>
<td>表示永不存在的值的类型</td>
<td><code>function error(): never {}</code></td>
<td>1. 用于总是抛出异常的函数<br>2. 无限循环函数的返回类型</td>
</tr>
<tr>
<td><code>void</code></td>
<td>表示没有返回值的函数</td>
<td><code>function fn(): void {}</code></td>
<td>1. 与<code>undefined</code>兼容<br>2. 常用于函数无显式返回值</td>
</tr>
</tbody></table>
<h4 id="新增复合类型"><a href="#新增复合类型" class="headerlink" title="新增复合类型"></a>新增复合类型</h4><table>
<thead>
<tr>
<th>类型</th>
<th>描述</th>
<th>示例</th>
<th>特点</th>
</tr>
</thead>
<tbody><tr>
<td><code>tuple</code></td>
<td>固定长度和类型的数组</td>
<td><code>let x: [string, number];</code></td>
<td>1. 长度固定<br>2. 每个位置类型固定<br>3. 越界元素使用联合类型</td>
</tr>
<tr>
<td><code>enum</code></td>
<td>枚举类型</td>
<td><code>enum Color {Red, Green}</code></td>
<td>1. 默认从0开始编号<br>2. 可手动赋值<br>3. 支持反向映射(数字枚举)</td>
</tr>
</tbody></table>
<h4 id="新增类型定义方式"><a href="#新增类型定义方式" class="headerlink" title="新增类型定义方式"></a>新增类型定义方式</h4><table>
<thead>
<tr>
<th>方式</th>
<th>描述</th>
<th>示例</th>
<th>区别</th>
</tr>
</thead>
<tbody><tr>
<td><code>type</code></td>
<td>类型别名,可定义各种类型组合</td>
<td><code>type Point = {...}</code></td>
<td>1. 更灵活,支持联合类型、交叉类型等高级类型<br>2. 不能重复声明</td>
</tr>
<tr>
<td><code>interface</code></td>
<td>接口,主要用于定义对象形状</td>
<td><code>interface Point {...}</code></td>
<td>1. 更适合定义对象结构<br>2. 支持声明合并<br>3. 可被类实现(implements)</td>
</tr>
</tbody></table>
<h4 id="类型对比"><a href="#类型对比" class="headerlink" title="类型对比"></a>类型对比</h4><h5 id="any-vs-unknown"><a href="#any-vs-unknown" class="headerlink" title="any vs unknown"></a><code>any</code> vs <code>unknown</code></h5><table>
<thead>
<tr>
<th>比较点</th>
<th><code>any</code></th>
<th><code>unknown</code></th>
</tr>
</thead>
<tbody><tr>
<td>类型安全</td>
<td>不安全,编译时不检查</td>
<td>安全,使用时需类型断言或收窄</td>
</tr>
<tr>
<td>赋值</td>
<td>可赋值给任意类型</td>
<td>只能赋值给<code>unknown</code>或<code>any</code></td>
</tr>
<tr>
<td>属性访问</td>
<td>可直接访问任意属性</td>
<td>不能直接访问属性</td>
</tr>
<tr>
<td>使用建议</td>
<td>尽量避免使用</td>
<td>优先使用替代<code>any</code></td>
</tr>
</tbody></table>
<h5 id="void-vs-undefined-vs-never"><a href="#void-vs-undefined-vs-never" class="headerlink" title="void vs undefined vs never"></a><code>void</code> vs <code>undefined</code> vs <code>never</code></h5><table>
<thead>
<tr>
<th>比较点</th>
<th><code>void</code></th>
<th><code>undefined</code></th>
<th><code>never</code></th>
</tr>
</thead>
<tbody><tr>
<td>含义</td>
<td>函数无返回值</td>
<td>未定义的值</td>
<td>永不存在的值</td>
</tr>
<tr>
<td>变量使用</td>
<td>不能作为变量类型</td>
<td>可以作为变量类型</td>
<td>不能作为变量实际类型</td>
</tr>
<tr>
<td>函数返回</td>
<td>函数无<code>return</code>或返回<code>undefined</code></td>
<td>必须显式返回<code>undefined</code></td>
<td>函数无法正常返回</td>
</tr>
<tr>
<td>赋值兼容</td>
<td>可接受<code>undefined</code></td>
<td>不能赋值给<code>void</code>变量</td>
<td>是所有类型的子类型</td>
</tr>
</tbody></table>
<h4 id="原始类型与包装类型"><a href="#原始类型与包装类型" class="headerlink" title="原始类型与包装类型"></a>原始类型与包装类型</h4><p>在JavaScript中的这些内置构造函数:<code> Number</code>、<code>String</code>、<code>Boolean</code>,用于创建对应的包装对象, 在日常开发时很少使用,在TypeScript中也是同理,所以在TypeScript中进行类型声明时,通常都是用小写的<code>number</code>、<code>string</code>、<code>bo olean</code>。</p>
<ol>
<li><p><strong>原始类型 VS 包装对象:</strong><br>原始类型:如number、string、boolean,在 JavaScript 中是简单数据<br>类型,它们在内存中占用空间少,处理速度快。<br>包装对象:如Number对象、String对象、Boolean对象,是复杂类型,在<br>内存中占用更多空间,在日常开发时很少由开发人员自己创建包装对象。</p>
</li>
<li><p><strong>自动装箱:</strong> JavaScript 在必要时会自动将原始类型包装成对象,以便调用方法或访问属性。</p>
</li>
</ol>
<h2 id="七-常用类型"><a href="#七-常用类型" class="headerlink" title="七.常用类型"></a>七.常用类型</h2><h3 id="1-any"><a href="#1-any" class="headerlink" title="1. any"></a>1. any</h3><p><code>any</code>:放弃对该变量的类型检查,可赋值给任意类型的变量</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>: <span class="hljs-built_in">any</span> <br>a = <span class="hljs-number">100</span><br>a = <span class="hljs-string">'TS你好'</span><br>a = <span class="hljs-literal">false</span><br></code></pre></td></tr></table></figure>
<h3 id="2-unknown"><a href="#2-unknown" class="headerlink" title="2. unknown"></a>2. unknown</h3><p><code>unknown:</code>未知类型</p>
<ol>
<li><code>unknown</code>可以理解为类型安全的具体类型</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>:<span class="hljs-built_in">unknown</span><br>a = <span class="hljs-number">99</span><br></code></pre></td></tr></table></figure>
<ol start="2">
<li><code>unknown</code>会强制开发者在使用前进行类型检查,可以通过<strong>类型判断</strong>或<strong>类型断言</strong>的方式实现安全操作变量。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 设置a的类型为unknown</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>: <span class="hljs-built_in">unknown</span><br>a = <span class="hljs-string">'hello'</span><br><span class="hljs-comment">//第一种方式:加类型判断</span><br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">'string'</span>){<br>x = a<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x)<br>}<br><span class="hljs-comment">//第二种方式:加断言</span><br>x = a <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span><br><span class="hljs-comment">//第三种方式:加断言</span><br>x = <<span class="hljs-built_in">string</span>>a<br></code></pre></td></tr></table></figure>
<ol start="3">
<li>读取<code>any</code>属性的任何属性都不会报错,而<code>unknown</code>则会。</li>
</ol>
<h3 id="3-never"><a href="#3-never" class="headerlink" title="3. never"></a>3. never</h3><p><code>never</code>:任何值都不是,不能有值。</p>
<ol>
<li>几乎不使用<code>never</code>,对变量赋值无意义。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> a :<span class="hljs-built_in">never</span><br><span class="hljs-comment">// 任何赋值都无意义</span><br></code></pre></td></tr></table></figure>
<ol start="2">
<li><p><code>never</code>一般是TypeScript主动推断出来的</p>
</li>
<li><p><code>never</code>可用于限制函数的返回值(如抛出错误的情况),表示函数不能结束,或者不能正常结束。</p>
</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">function</span> <span class="hljs-title function_">throwError</span>(<span class="hljs-params"><span class="hljs-attr">str</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-built_in">never</span>{<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'程序异常退出'</span>+str)<br>}<br></code></pre></td></tr></table></figure>
<h3 id="4-void"><a href="#4-void" class="headerlink" title="4. void"></a>4. void</h3><p><code>void</code>:用于函数返回值声明,表示函数返回值为空。</p>
<ol>
<li>函数返回值为空,调用者也不应该依赖其返回值进行任何操作。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs ts"><br><span class="hljs-keyword">const</span> logMsg = (<span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span>):<span class="hljs-function"><span class="hljs-params">void</span> =></span>{<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br>}<br><span class="hljs-title function_">logMsg</span>(<span class="hljs-string">'TS你好'</span>)<br></code></pre></td></tr></table></figure>
<blockquote>
<p>注意:编码者没有编写return指定函数返回值,所以logMessage函数是没有显式返回值的,但会有一个隐式返回值 ,是<code>undefined</code>。虽然函数返回类型为<code>void</code>,但也是可以接受undefined的,简单记: <code>undefined</code>是<code>void</code>可以接受的一种“空”。</p>
</blockquote>
<ol start="2">
<li>对函数返回值声明为<code>void</code>的函数,TS接受如下写法</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 无警告</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">logMessage</span>(<span class="hljs-params"><span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-built_in">void</span>{<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br>}<br><span class="hljs-comment">// 无警告</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">logMessage</span>(<span class="hljs-params"><span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-built_in">void</span>{<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br><span class="hljs-keyword">return</span>;<br>}<br><span class="hljs-comment">// 无警告</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">logMessage</span>(<span class="hljs-params"><span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-built_in">void</span>{<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br><span class="hljs-keyword">return</span> <span class="hljs-literal">undefined</span><br>}<br></code></pre></td></tr></table></figure>
<ol start="3">
<li><strong>返回值类型为void的函数,调用者不应依赖其返回值进行任何操作!</strong>:理解来说,被<code>void</code>声明的函数返回值,TS希望开发者从语义层面上不要关注其返回值,不期望依赖该函数用于其他的操作。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">function</span> <span class="hljs-title function_">logMessage</span>(<span class="hljs-params"><span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-built_in">void</span>{<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br>}<br><span class="hljs-keyword">let</span> result = <span class="hljs-title function_">logMessage</span>(<span class="hljs-string">'你好'</span>)<br><span class="hljs-keyword">if</span>(result){ <span class="hljs-comment">// 此行报错:无法测试 "void" 类型的表达式的真实性</span><br><span class="hljs-variable language_">console</span>.<br></code></pre></td></tr></table></figure>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">function</span> <span class="hljs-title function_">logMessage</span>(<span class="hljs-params"><span class="hljs-attr">msg</span>:<span class="hljs-built_in">string</span></span>):<span class="hljs-literal">undefined</span>{<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br>}<br><span class="hljs-keyword">let</span> result = <span class="hljs-title function_">logMessage</span>(<span class="hljs-string">'你好'</span>)<br><span class="hljs-keyword">if</span>(result){ <span class="hljs-comment">// 此行无警告</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'logMessage'</span>)<br></code></pre></td></tr></table></figure>
<p><strong>理解 void 与 undefined:</strong><br><code>void</code>是一个广泛的概念,用来表达“空”,而 <code>undefined</code>则是这种“空”的具体实现。<br>因此可以说 <code>undefined</code>是<code>void</code>能接受的一种“空”的状态。也可以理解为: <code>void</code>包含<code>undefined</code>,但<code>void</code>所表达的语义超越了<code>undefined</code>, <code>void</code>是一种意图上的约定,而不仅仅是特定值的限制。</p>
<p><strong>总结:</strong></p>
<p>如果一个函数返回类型为<code>void</code>,那么:</p>
<ol>
<li>从语法上讲:函数是可以返回<code>undefined</code>的,至于显式返回,还是隐式返回,这无所谓!</li>
<li>从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作!即使我们知道它返回了<code>undefined</code>。</li>
</ol>
<h3 id="5-object"><a href="#5-object" class="headerlink" title="5.object"></a>5.object</h3><h4 id="object与Object"><a href="#object与Object" class="headerlink" title="object与Object"></a>object与Object</h4><ul>
<li><p><code>object</code>:所有非原始类型,可存储对象,函数,数组等。</p>
</li>
<li><p><code>Object</code>:所有可以调用 Object方法的类型,即除了<code>undefined</code>和<code>null</code>的任何值</p>
</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">a</span>:<span class="hljs-built_in">object</span> <span class="hljs-comment">//a的值可以是任何【非原始类型】,包括:对象、函数、数组等</span><br><span class="hljs-comment">// 以下代码,是将【非原始类型】赋给a,所以均符合要求</span><br>a = {}<br>a = {<span class="hljs-attr">name</span>:<span class="hljs-string">'张三'</span>}<br>a = [<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>,<span class="hljs-number">7</span>,<span class="hljs-number">9</span>]<br>a = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){}<br>a = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">'123'</span>)<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {}<br>a = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>()<br><span class="hljs-comment">// 以下代码,是将【原始类型】赋给a,有警告</span><br>a = <span class="hljs-number">1</span> <span class="hljs-comment">// 警告:不能将类型“number”分配给类型“object”</span><br>a = <span class="hljs-literal">true</span> <span class="hljs-comment">// 警告:不能将类型“boolean”分配给类型“object”</span><br>a = <span class="hljs-string">'你好'</span> <span class="hljs-comment">// 警告:不能将类型“string”分配给类型“object”</span><br>a = <span class="hljs-literal">null</span> <span class="hljs-comment">// 警告:不能将类型“null”分配给类型“object”</span><br>a = <span class="hljs-literal">undefined</span> <span class="hljs-comment">// 警告:不能将类型“undefined”分配给类型“object”</span><br><br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">b</span>:<span class="hljs-title class_">Object</span> <span class="hljs-comment">//b的值必须是Object的实例对象(除去undefined和null的任何值)</span><br><span class="hljs-comment">// 以下代码,均无警告,因为给a赋的值,都是Object的实例对象</span><br>b = {}<br>b = {<span class="hljs-attr">name</span>:<span class="hljs-string">'张三'</span>}<br>b = [<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>,<span class="hljs-number">7</span>,<span class="hljs-number">9</span>]<br>b = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){}<br>b = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">'123'</span>)<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {}<br>b = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>()<br>b = <span class="hljs-number">1</span> <span class="hljs-comment">// 1不是Object的实例对象,但其包装对象是Object的实例</span><br>b = <span class="hljs-literal">true</span> <span class="hljs-comment">// truue不是Object的实例对象,但其包装对象是Object的实例</span><br>b = <span class="hljs-string">'你好'</span> <span class="hljs-comment">// “你好”不是Object的实例对象,但其包装对象是Object的实例</span><br><span class="hljs-comment">// 以下代码均有警告</span><br>b = <span class="hljs-literal">null</span> <span class="hljs-comment">// 警告:不能将类型“null”分配给类型“Object”</span><br>b = <span class="hljs-literal">undefined</span> <span class="hljs-comment">// 警告:不能将类型“undefined”分配给类型“Object”</span><br></code></pre></td></tr></table></figure>
<h4 id="声明类型"><a href="#声明类型" class="headerlink" title="声明类型"></a>声明类型</h4><h5 id="声明对象类型"><a href="#声明对象类型" class="headerlink" title="声明对象类型"></a>声明对象类型</h5><ol>
<li>对象类型字面量</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 限制person1对象必须有name属性,age为可选属性</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">person1</span>: { <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">age</span>?: <span class="hljs-built_in">number</span> }<br><span class="hljs-comment">// 含义同上,也能用分号做分隔</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">person2</span>: { <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>; <span class="hljs-attr">age</span>?: <span class="hljs-built_in">number</span> }<br><span class="hljs-comment">// 含义同上,也能用换行做分隔</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">person3</span>: {<br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>?: <span class="hljs-built_in">number</span><br>}<br><span class="hljs-comment">// 如下赋值均可以</span><br>person1 = {<span class="hljs-attr">name</span>:<span class="hljs-string">'李四'</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">18</span>}<br>person2 = {<span class="hljs-attr">name</span>:<span class="hljs-string">'张三'</span>}<br>person3 = {<span class="hljs-attr">name</span>:<span class="hljs-string">'王五'</span>}<br><span class="hljs-comment">// 如下赋值不合法,因为person3的类型限制中,没有对gender属性的说明</span><br>person3 = {<span class="hljs-attr">name</span>:<span class="hljs-string">'王五'</span>,<span class="hljs-attr">gender</span>:<span class="hljs-string">'男'</span>}<br></code></pre></td></tr></table></figure>
<ol start="2">
<li>索引签名:允许定义对象可以具有<strong>任意数量</strong>的属性,这些属性的键和类型是<strong>可变的</strong>。常用于:描述类型不确定的属性,(具有动态属性的对象)。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 限制person对象必须有name属性,可选age属性但值必须是数字,同时可以有任意数</span><br>量、任意类型的其他属性<br><span class="hljs-keyword">let</span> <span class="hljs-attr">person</span>: {<br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>?: <span class="hljs-built_in">number</span><br>[<span class="hljs-attr">key</span>: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">any</span> <span class="hljs-comment">// 索引签名,完全可以不用key这个单词,换成其他的也可以</span><br>}<br><span class="hljs-comment">// 赋值合法</span><br>person = {<br><span class="hljs-attr">name</span>:<span class="hljs-string">'张三'</span>,<br><span class="hljs-attr">age</span>:<span class="hljs-number">18</span>,<br><span class="hljs-attr">gender</span>:<span class="hljs-string">'男'</span><br>}<br></code></pre></td></tr></table></figure>
<h5 id="声明函数类型"><a href="#声明函数类型" class="headerlink" title="声明函数类型"></a>声明函数类型</h5><p><strong>函数类型注解</strong></p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">let</span> <span class="hljs-attr">count</span>: <span class="hljs-function">(<span class="hljs-params"><span class="hljs-attr">a</span>: <span class="hljs-built_in">number</span>, <span class="hljs-attr">b</span>: <span class="hljs-built_in">number</span></span>) =></span> <span class="hljs-built_in">number</span><br>count = <span class="hljs-keyword">function</span> (<span class="hljs-params">x, y</span>) {<br><span class="hljs-keyword">return</span> x + y<br>}<br></code></pre></td></tr></table></figure>
<blockquote>
<ul>
<li><p>TypeScript 中的=>在函数类型声明时表示函数类型,描述其参数类型和返回类型。</p>
</li>
<li><p>JavaScript 中的=>是一种定义函数的语法,是具体的函数实现。</p>
</li>
</ul>
</blockquote>
<h5 id="声明数组类型"><a href="#声明数组类型" class="headerlink" title="声明数组类型"></a>声明数组类型</h5><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">//类型声明</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">arr</span>: <span class="hljs-built_in">string</span>[]<br><span class="hljs-comment">//泛型定义</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">arr2</span>: <span class="hljs-title class_">Array</span><<span class="hljs-built_in">string</span>><br></code></pre></td></tr></table></figure>
<h3 id="6-tuple"><a href="#6-tuple" class="headerlink" title="6.tuple"></a>6.tuple</h3><p><code>Tuple</code>是一种特殊的数组类型,可以存储<strong>固定数量</strong>的元素,并且每个元素的类型是<strong>已知</strong>的且<strong>可以不同</strong>。元组用于精确描述一组值的类型,<code> ?</code>表示可选元素。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 第一个元素必须是 string 类型,第二个元素必须是 number 类型。</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">arr1</span>: [<span class="hljs-built_in">string</span>,<span class="hljs-built_in">number</span>]<br><span class="hljs-comment">// 第一个元素必须是 number 类型,第二个元素是可选的,如果存在,必须是 boolean 类型。</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">arr2</span>: [<span class="hljs-built_in">number</span>,<span class="hljs-built_in">boolean</span>?]<br><span class="hljs-comment">// 第一个元素必须是 number 类型,后面的元素可以是任意数量的 string 类型</span><br><span class="hljs-keyword">let</span> <span class="hljs-attr">arr3</span>: [<span class="hljs-built_in">number</span>,...<span class="hljs-built_in">string</span>[]]<br><span class="hljs-comment">// 可以赋值</span><br>arr1 = [<span class="hljs-string">'hello'</span>,<span class="hljs-number">123</span>]<br>arr2 = [<span class="hljs-number">100</span>,<span class="hljs-literal">false</span>]<br>arr2 = [<span class="hljs-number">200</span>]<br>arr3 = [<span class="hljs-number">100</span>,<span class="hljs-string">'hello'</span>,<span class="hljs-string">'world'</span>]<br>arr3 = [<span class="hljs-number">100</span>]<br><span class="hljs-comment">// 不可以赋值,arr1声明时是两个元素,赋值的是三个</span><br>arr1 = [<span class="hljs-string">'hello'</span>,<span class="hljs-number">123</span>,<span class="hljs-literal">false</span>]<br></code></pre></td></tr></table></figure>
<h3 id="7-enum"><a href="#7-enum" class="headerlink" title="7.enum"></a>7.enum</h3><p> <code>enum</code>:枚举,定义一组命名常量,它能增强代码的可读性,也让代码更好维护。也可以指定枚举成员的初始值,其后的成员值会自动递增。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Direction</span> {<br> <span class="hljs-title class_">Up</span>,<br> <span class="hljs-title class_">Down</span>,<br> <span class="hljs-title class_">Left</span>,<br> <span class="hljs-title class_">Right</span><br>}<br></code></pre></td></tr></table></figure>
<ul>
<li><strong>数字枚举</strong>:数字枚举一种最常见的枚举类型,其成员的值会自动递增,且数字枚举还具备反向映射的特点,在下面代码的打印中,不难发现:可以通过值来获取对应的枚举成员名称 。好处是语义性更强,便于维护。</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// 定义一个描述【上下左右】方向的枚举Direction</span><br><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Direction</span> {<br><span class="hljs-title class_">Up</span>,<br><span class="hljs-title class_">Down</span>,<br><span class="hljs-title class_">Left</span>,<br><span class="hljs-title class_">Right</span><br>}<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Direction</span>) <span class="hljs-comment">// 打印Direction会看到如下内容</span><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">{</span><br><span class="hljs-comment">0:'Up',</span><br><span class="hljs-comment">1:'Down',</span><br><span class="hljs-comment">2:'Left',</span><br><span class="hljs-comment">3:'Right',</span><br><span class="hljs-comment">Up:0,</span><br><span class="hljs-comment">Down:1,</span><br><span class="hljs-comment">Left:2,</span><br><span class="hljs-comment">Right:3</span><br><span class="hljs-comment">}</span><br><span class="hljs-comment">*/</span><br><span class="hljs-comment">// 反向映射</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Direction</span>.<span class="hljs-property">Up</span>)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Direction</span>[<span class="hljs-number">0</span>])<br><span class="hljs-comment">// 此行代码报错,枚举中的属性是只读的</span><br><span class="hljs-title class_">Direction</span>.<span class="hljs-property">Up</span> = <span class="hljs-string">'shang'</span><br></code></pre></td></tr></table></figure>
<ul>
<li><strong>字符串枚举</strong>:同理,枚举成员的值是字符串</li>
<li><strong>常量枚举:</strong> 常量枚举是一种特殊枚举类型,它使用 const关键字定义,在编译时会被内联,避免生成一些额外的代码,推荐使用。</li>
</ul>
<blockquote>
<p><strong>何为编译时内联?</strong><br>所谓“内联”其实就是 TypeScript 在编译时,会将枚举成员引用替换为它们的实际值,而不是生成额外的枚举对象。这可以减少生成JavaScript 代码量,并提高运行时性能。</p>
</blockquote>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Directions</span> {<br><span class="hljs-title class_">Up</span>,<br><span class="hljs-title class_">Down</span>,<br><span class="hljs-title class_">Left</span>,<br><span class="hljs-title class_">Right</span><br>}<br><span class="hljs-keyword">let</span> x = <span class="hljs-title class_">Directions</span>.<span class="hljs-property">Up</span>;<br><br><br><span class="hljs-meta">"use strict"</span>;<br><span class="hljs-keyword">let</span> x = <span class="hljs-number">0</span> <span class="hljs-comment">/* Directions.Up */</span>;<br></code></pre></td></tr></table></figure>
<h3 id="8-type"><a href="#8-type" class="headerlink" title="8.type"></a>8.type</h3><p><code>type</code>:为任何类型创建别名,让代码更简洁,可读性更强;同时更方便的进行类型复用和扩展。</p>
<ol>
<li><strong>类型别名</strong>:使用 type关键字定义, type后跟类型名称,即类型别名。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">type</span> num = <span class="hljs-built_in">number</span>;<br><span class="hljs-keyword">let</span> <span class="hljs-attr">price</span>: num<br>price = <span class="hljs-number">100</span><br></code></pre></td></tr></table></figure>
<ol start="2">
<li><strong>联合类型</strong>:联合类型是一种高级类型,它表示一个值可以是几种不同类型之一。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">type</span> <span class="hljs-title class_">Status</span> = <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Gender</span> = <span class="hljs-string">'男'</span> | <span class="hljs-string">'女'</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">printStatus</span>(<span class="hljs-params"><span class="hljs-attr">status</span>: <span class="hljs-title class_">Status</span></span>) {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(status);<br>}<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">logGender</span>(<span class="hljs-params"><span class="hljs-attr">str</span>:<span class="hljs-title class_">Gender</span></span>){<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(str)<br>}<br><span class="hljs-title function_">printStatus</span>(<span class="hljs-number">404</span>);<br><span class="hljs-title function_">printStatus</span>(<span class="hljs-string">'200'</span>);<br><span class="hljs-title function_">printStatus</span>(<span class="hljs-string">'501'</span>);<br><span class="hljs-title function_">logGender</span>(<span class="hljs-string">'男'</span>)<br><span class="hljs-title function_">logGender</span>(<span class="hljs-string">'女'</span>)<br></code></pre></td></tr></table></figure>
<ol start="3">
<li><strong>交叉类型</strong>:允许将多个类型合并为一个类型。合并后的类型将拥有所有被合并类型的成员。交叉类型通常用于对象类型。</li>
</ol>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">//面积</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Area</span> = {<br><span class="hljs-attr">height</span>: <span class="hljs-built_in">number</span>; <span class="hljs-comment">//高</span><br><span class="hljs-attr">width</span>: <span class="hljs-built_in">number</span>; <span class="hljs-comment">//宽</span><br>};<br><span class="hljs-comment">//地址</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">Address</span> = {<br><span class="hljs-attr">num</span>: <span class="hljs-built_in">number</span>; <span class="hljs-comment">//楼号</span><br><span class="hljs-attr">cell</span>: <span class="hljs-built_in">number</span>; <span class="hljs-comment">//单元号</span><br><span class="hljs-attr">room</span>: <span class="hljs-built_in">string</span>; <span class="hljs-comment">//房间号</span><br>};<br><span class="hljs-comment">// 定义类型House,且House是Area和Address组成的交叉类型</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">House</span> = <span class="hljs-title class_">Area</span> & <span class="hljs-title class_">Address</span>;<br><span class="hljs-keyword">const</span> <span class="hljs-attr">house</span>: <span class="hljs-title class_">House</span> = {<br><span class="hljs-attr">height</span>: <span class="hljs-number">180</span>,<br><span class="hljs-attr">width</span>: <span class="hljs-number">75</span>,<br><span class="hljs-attr">num</span>: <span class="hljs-number">6</span>,<br><span class="hljs-attr">cell</span>: <span class="hljs-number">3</span>,<br><span class="hljs-attr">room</span>: <span class="hljs-string">'702'</span><br>};<br></code></pre></td></tr></table></figure>
<h3 id="9-特殊情况"><a href="#9-特殊情况" class="headerlink" title="9.特殊情况"></a>9.特殊情况</h3><p>使用<strong>类型声明</strong>限制函数返回值为void时, TypeScript并不会严格要求函数返回空。</p>
<ul>
<li><p>为什么?</p>
</li>
<li><p>是为了确保如下代码成立,我们知道 <code>Array.prototype.push</code> 的返回值是一个数字,而 <code>Array.prototype.forEach</code>方法期望其回调的返回类型是<code>void</code>。</p>
</li>
</ul>
<h3 id="10-属性修饰符"><a href="#10-属性修饰符" class="headerlink" title="10.属性修饰符"></a>10.属性修饰符</h3><table>
<thead>
<tr>
<th>修饰符</th>
<th>含义</th>
<th>具体规则</th>
</tr>
</thead>
<tbody><tr>
<td><code>public</code></td>
<td>公开的</td>
<td>可以被<strong>类内部、子类、类外部</strong>访问</td>
</tr>
<tr>
<td><code>protected</code></td>
<td>受保护的</td>
<td>可以被<strong>类内部、子类</strong>访问</td>
</tr>
<tr>
<td><code>private</code></td>
<td>私有的</td>
<td>可以被<strong>类内部</strong>访问</td>
</tr>
<tr>
<td><code>readonly</code></td>
<td>只读属性</td>
<td>属性无法修改</td>
</tr>
</tbody></table>
<h4 id="属性的简写形式"><a href="#属性的简写形式" class="headerlink" title="属性的简写形式"></a>属性的简写形式</h4><p>在构造器写类型注解和属性修饰符即可。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {<br> <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"> <span class="hljs-keyword">public</span> <span class="hljs-attr">name</span>:<span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"> <span class="hljs-keyword">public</span> <span class="hljs-attr">age</span>:<span class="hljs-built_in">number</span> </span><br><span class="hljs-params"></span>){<br> ...<br>}<br>}<br></code></pre></td></tr></table></figure>
<h4 id="public修饰符"><a href="#public修饰符" class="headerlink" title="public修饰符"></a>public修饰符</h4><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs ts"><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {<br><span class="hljs-comment">// name写了public修饰符,age没写修饰符,最终都是public修饰符</span><br><span class="hljs-keyword">public</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span><br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span></span>) {<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">age</span> = age<br>}<br><span class="hljs-title function_">speak</span>(<span class="hljs-params"></span>) {<br><span class="hljs-comment">// 类的【内部】可以访问public修饰的name和age</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`我叫:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>,今年<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>岁`</span>)<br>}<br>}<br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">'张三'</span>, <span class="hljs-number">18</span>)<br><span class="hljs-comment">// 类的【外部】可以访问public修饰的属性</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-property">name</span>)<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Person</span> {<br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span></span>) {<br><span class="hljs-variable language_">super</span>(name, age)<br>}<br><span class="hljs-title function_">study</span>(<span class="hljs-params"></span>) {<br><span class="hljs-comment">// 【子类中】可以访问父类中public修饰的:name属性、age属性</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>岁的<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>正在努力学习`</span>)<br>}<br><br><br></code></pre></td></tr></table></figure>
<h4 id="protected修饰符"><a href="#protected修饰符" class="headerlink" title="protected修饰符"></a>protected修饰符</h4><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs ts"><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {<br><span class="hljs-comment">// name和age是受保护属性,不能在类外部访问,但可以在【类】与【子类】中访问</span><br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"><span class="hljs-keyword">protected</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">protected</span> <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span></span><br><span class="hljs-params"></span>) {}<br><span class="hljs-comment">// getDetails是受保护方法,不能在类外部访问,但可以在【类】与【子类】中访问</span><br><span class="hljs-keyword">protected</span> <span class="hljs-title function_">getDetails</span>(): <span class="hljs-built_in">string</span> {<br><span class="hljs-comment">// 类中能访问受保护的name和age属性</span><br><span class="hljs-keyword">return</span> <span class="hljs-string">`我叫:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>,年龄是:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>`</span><br>}<br><span class="hljs-comment">// introduce是公开方法,类、子类、类外部都能使用</span><br><span class="hljs-title function_">introduce</span>(<span class="hljs-params"></span>) {<br><span class="hljs-comment">// 类中能访问受保护的getDetails方法</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getDetails</span>());<br>}<br>}<br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">'杨超越'</span>,<span class="hljs-number">18</span>)<br><span class="hljs-comment">// 可以在类外部访问introduce</span><br>p1.<span class="hljs-title function_">introduce</span>()<br><span class="hljs-comment">// 以下代码均报错</span><br><span class="hljs-comment">// p1.getDetails()</span><br><span class="hljs-comment">// p1.name</span><br><span class="hljs-comment">// p1.age</span><br></code></pre></td></tr></table></figure>
<h4 id="private修饰符"><a href="#private修饰符" class="headerlink" title="private修饰符"></a>private修饰符</h4><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> {<br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>,</span><br><span class="hljs-params"><span class="hljs-comment">// IDCard属性为私有的(private)属性,只能在【类内部】使用</span></span><br><span class="hljs-params"><span class="hljs-keyword">private</span> <span class="hljs-title class_">IDCard</span>: <span class="hljs-built_in">string</span></span><br><span class="hljs-params"></span>) { }<br><span class="hljs-keyword">private</span> <span class="hljs-title function_">getPrivateInfo</span>(<span class="hljs-params"></span>){<br><span class="hljs-comment">// 类内部可以访问私有的(private)属性 —— IDCard</span><br><span class="hljs-keyword">return</span> <span class="hljs-string">`身份证号码为:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.IDCard}</span>`</span><br>}<br><span class="hljs-title function_">getInfo</span>(<span class="hljs-params"></span>) {<br><span class="hljs-comment">// 类内部可以访问受保护的(protected)属性 —— name和age</span><br><span class="hljs-keyword">return</span> <span class="hljs-string">`我叫: <span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>, 今年刚满<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>岁`</span>;<br>}<br><span class="hljs-title function_">getFullInfo</span>(<span class="hljs-params"></span>){<br><span class="hljs-comment">// 类内部可以访问公开的getInfo方法,也可以访问私有的getPrivateInfo方法</span><br><span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getInfo</span>() + <span class="hljs-string">','</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getPrivateInfo</span>()<br>}<br>}<br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">'张三'</span>,<span class="hljs-number">18</span>,<span class="hljs-string">'110114198702034432'</span>)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-title function_">getFullInfo</span>())<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-title function_">getInfo</span>())<br><span class="hljs-comment">// 以下代码均报错</span><br><span class="hljs-comment">// p1.name</span><br><span class="hljs-comment">// p1.age</span><br><span class="hljs-comment">// p1.IDCard</span><br><span class="hljs-comment">// p1.getPrivateInfo()</span><br></code></pre></td></tr></table></figure>
<h4 id="readonly修饰符"><a href="#readonly修饰符" class="headerlink" title="readonly修饰符"></a>readonly修饰符</h4><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span> {<br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-keyword">readonly</span> <span class="hljs-attr">vin</span>: <span class="hljs-built_in">string</span>, <span class="hljs-comment">//车辆识别码,为只读属性</span></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-keyword">readonly</span> <span class="hljs-attr">year</span>: <span class="hljs-built_in">number</span>,<span class="hljs-comment">//出厂年份,为只读属性</span></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">color</span>: <span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">sound</span>: <span class="hljs-built_in">string</span></span><br><span class="hljs-params"></span>) { }<br><span class="hljs-comment">// 打印车辆信息</span><br><span class="hljs-title function_">displayInfo</span>(<span class="hljs-params"></span>) {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`</span><br><span class="hljs-string">识别码:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.vin}</span>,</span><br><span class="hljs-string">出厂年份:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.year}</span>,</span><br><span class="hljs-string">颜色:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.color}</span>,</span><br><span class="hljs-string">音响:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.sound}</span></span><br><span class="hljs-string">`</span>);<br>}<br>}<br><span class="hljs-keyword">const</span> car = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>(<span class="hljs-string">'1HGCM82633A123456'</span>, <span class="hljs-number">2018</span>, <span class="hljs-string">'黑色'</span>, <span class="hljs-string">'Bose音响'</span>);<br>car.<span class="hljs-title function_">displayInfo</span>()<br><span class="hljs-comment">// 以下代码均错误:不能修改 readonly 属性</span><br><span class="hljs-comment">// car.vin = '897WYE87HA8SGDD8SDGHF';</span><br><span class="hljs-comment">// car.year = 2020;</span><br></code></pre></td></tr></table></figure>
<h3 id="11-抽象类"><a href="#11-抽象类" class="headerlink" title="11.抽象类"></a>11.抽象类</h3><p><strong>定义:</strong> 抽象类是一种无法被实例化的类,专门用来定义类的结构和行为,类中可以写抽象方法,也可以写具体实现。抽象类主要用来为其派生类提供一个基础结构,要求其派生类必须实现其中的抽象方法。</p>
<p><strong>简单来说:</strong> 抽象类不能实例化,其意义是可以被继承,抽象类里可以有普通方法、也可以有抽象方法。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Package</span>{<br> <span class="hljs-comment">// 构造方法</span><br> <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"> <span class="hljs-keyword">public</span> <span class="hljs-attr">weight</span>:<span class="hljs-built_in">number</span></span><br><span class="hljs-params"> </span>){<br><br> }<br> <span class="hljs-comment">// 抽象方法</span><br> <span class="hljs-keyword">abstract</span> <span class="hljs-title function_">calculate</span>():<span class="hljs-built_in">number</span><br> <span class="hljs-comment">// 具体方法</span><br> <span class="hljs-title function_">printPackage</span>(<span class="hljs-params"></span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`包裹重量为:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.weight}</span>\n运费为:<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.calculate()}</span>`</span>)<br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">StandardPackage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Package</span>{<br> <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"> <span class="hljs-attr">weight</span>:<span class="hljs-built_in">number</span>,</span><br><span class="hljs-params"> <span class="hljs-keyword">public</span> <span class="hljs-attr">unitPrice</span>:<span class="hljs-built_in">number</span></span><br><span class="hljs-params"></span><br><span class="hljs-params"> </span>){<br> <span class="hljs-variable language_">super</span>(weight)<br> }<br> <span class="hljs-title function_">calculate</span>(): <span class="hljs-built_in">number</span> {<br> <span class="hljs-keyword">return</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">weight</span> * <span class="hljs-variable language_">this</span>.<span class="hljs-property">unitPrice</span>)<br> }<br>}<br><br><span class="hljs-keyword">const</span> pkg1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">StandardPackage</span>(<span class="hljs-number">10</span>,<span class="hljs-number">5</span>)<br>pkg1.<span class="hljs-title function_">printPackage</span>()<br></code></pre></td></tr></table></figure>
<p><strong>总结:何时使用抽象类</strong></p>
<ol>
<li><p><strong>定义通用接口</strong>:为一组相关的类定义通用的行为(方法或属性)时。</p>
</li>
<li><p><strong>提供基础实现:</strong> 在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承这些实现。</p>
</li>
<li><p><strong>确保关键实现:</strong> 强制派生类实现一些关键行为。</p>
</li>
<li><p><strong>共享代码和逻辑:</strong> 当多个类需要共享部分代码时,抽象类可以避免代码重复。</p>
</li>
</ol>
<h3 id="12-interface"><a href="#12-interface" class="headerlink" title="12.interface"></a>12.interface</h3><p><code>interface</code>:一种定义结构的方式,主要作用是为:类、对象、函数等规定一种契约,这样可以确保代码的一致性和类型安全,但要注意interface只能定义格式,不能包含任何实现 !</p>
<ul>
<li>定义类结构</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">PersonInterface</span> {<br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span><br><span class="hljs-title function_">speak</span>(<span class="hljs-attr">n</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span><br>}<br><span class="hljs-comment">// 定义一个类 Person,实现 PersonInterface 接口</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">PersonInterface</span> {<br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span></span><br><span class="hljs-params"></span>) { }<br><span class="hljs-comment">// 实现接口中的 speak 方法</span><br><span class="hljs-title function_">speak</span>(<span class="hljs-attr">n</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {<br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < n; i++) {<br><span class="hljs-comment">// 打印出包含名字和年龄的问候语句</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`你好,我叫<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>,我的年龄是<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>`</span>);<br>}<br>}<br>}<br><span class="hljs-comment">// 创建一个 Person 类的实例 p1,传入名字 'tom' 和年龄 18</span><br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">'tom'</span>, <span class="hljs-number">18</span>);<br>p1.<span class="hljs-title function_">speak</span>(<span class="hljs-number">3</span>)<br></code></pre></td></tr></table></figure>
<ul>
<li>定义对象结构</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">UserInterface</span> {<br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-keyword">readonly</span> <span class="hljs-attr">gender</span>: <span class="hljs-built_in">string</span> <span class="hljs-comment">// 只读属性</span><br><span class="hljs-attr">age</span>?: <span class="hljs-built_in">number</span> <span class="hljs-comment">// 可选属性</span><br><span class="hljs-attr">run</span>: <span class="hljs-function">(<span class="hljs-params"><span class="hljs-attr">n</span>: <span class="hljs-built_in">number</span></span>) =></span> <span class="hljs-built_in">void</span><br>}<br><span class="hljs-keyword">const</span> <span class="hljs-attr">user</span>: <span class="hljs-title class_">UserInterface</span> = {<br><span class="hljs-attr">name</span>: <span class="hljs-string">"张三"</span>,<br><span class="hljs-attr">gender</span>: <span class="hljs-string">'男'</span>,<br><span class="hljs-attr">age</span>: <span class="hljs-number">18</span>,<br><span class="hljs-title function_">run</span>(<span class="hljs-params">n</span>) {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`奔跑了<span class="hljs-subst">${n}</span>米`</span>)<br>}<br>};<br></code></pre></td></tr></table></figure>
<ul>
<li>定义函数结构</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">CountInterface</span> {<br>(<span class="hljs-attr">a</span>: <span class="hljs-built_in">number</span>, <span class="hljs-attr">b</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">number</span>;<br>}<br><span class="hljs-keyword">const</span> <span class="hljs-attr">count</span>: <span class="hljs-title class_">CountInterface</span> = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =></span> {<br><span class="hljs-keyword">return</span> x + y<br>}<br></code></pre></td></tr></table></figure>
<ul>
<li><p><strong>接口继承:</strong> 使用<code>extends</code>关键字实现接口继承</p>
</li>
<li><p>接口自动合并</p>
</li>
</ul>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// PersonInterface接口</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">PersonInterface</span> {<br><span class="hljs-comment">// 属性声明</span><br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span><br>}<br><span class="hljs-comment">// 给PersonInterface接口添加新属性</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">PersonInterface</span> {<br><span class="hljs-comment">// 方法声明</span><br><span class="hljs-title function_">speak</span>(): <span class="hljs-built_in">void</span><br>}<br><span class="hljs-comment">// Person类实现PersonInterface</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">PersonInterface</span> {<br><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span><br><span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span><br><span class="hljs-comment">// 构造器</span><br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span></span>) {<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">age</span> = age<br>}<br><span class="hljs-comment">// 方法</span><br><span class="hljs-title function_">speak</span>(<span class="hljs-params"></span>) {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'你好!我是老师:'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span>)<br>}<br>}<br></code></pre></td></tr></table></figure>
<blockquote>
<p><strong>何时使用接口</strong>:</p>
<ol>
<li><p><strong>定义对象格式:</strong> 描述数据类型、API响应格式、配置对象……</p>
</li>
<li><p><strong>类的契约:</strong> 规定一个类需要视线的哪些方法和属性</p>
</li>
<li><p><strong>扩展已有接口:</strong> 一般用于扩展第三方库的类型</p>
</li>
</ol>
</blockquote>
<h3 id="13-相似概念的区别"><a href="#13-相似概念的区别" class="headerlink" title="13.相似概念的区别"></a>13.相似概念的区别</h3><h4 id="13-1-interface-与-type-的区别"><a href="#13-1-interface-与-type-的区别" class="headerlink" title="13.1 interface 与 type 的区别"></a>13.1 interface 与 type 的区别</h4><ul>
<li><p><strong>相同点:</strong> interface和type 都可以用于定义对象结构,在定义对象结构时两者可以互换。</p>
</li>
<li><p><strong>不同点:</strong></p>
<ol>
<li><p><code>interface</code>:更专注于定义对象和类的结构,支持继承、合并。</p>
</li>
<li><p><code>type</code>:可以定义<strong>类型别名</strong>、<strong>联合类型</strong>、<strong>交叉类型</strong>,但不支持继承和自动合并。</p>
</li>
</ol>
</li>
</ul>
<p>简言之,对于需要复杂继承和扩展的类型,推荐使用<code>interface</code>&<code>extends</code>实现继承。</p>
<h4 id="13-2-interface与抽象类的区别"><a href="#13-2-interface与抽象类的区别" class="headerlink" title="13.2 interface与抽象类的区别"></a>13.2 interface与抽象类的区别</h4><ul>
<li><p><strong>相同点:</strong> 都用于定义一个类的格式</p>
</li>
<li><p><strong>不同点:</strong></p>
</li>
</ul>
<p> 1. 接口:只能描述结构,不能有任何实现代码,一个类可以有多个接口。</p>
<p> 2. 抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类。</p>
<h2 id="八-泛型"><a href="#八-泛型" class="headerlink" title="八.泛型"></a>八.泛型</h2><p><strong>定义:</strong> 泛型运行我们在定义函数,类或接口时,使用类型参数来表示未指定的类型,这些参数在具体使用时,才被指定具体的类型,泛型能让同一段代码适用于多种类型,同时仍然保持类型的安全性。</p>
<h3 id="泛型函数"><a href="#泛型函数" class="headerlink" title="泛型函数"></a>泛型函数</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><br><span class="hljs-keyword">function</span> logData<T>(<span class="hljs-attr">data</span>:T){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(data)<br>}<br>logData<<span class="hljs-built_in">number</span>>(<span class="hljs-number">100</span>)<br>logData<<span class="hljs-built_in">string</span>>(<span class="hljs-string">'Hi'</span>)<br></code></pre></td></tr></table></figure>
<p>注:泛型可以有多个</p>
<h3 id="泛型接口"><a href="#泛型接口" class="headerlink" title="泛型接口"></a>泛型接口</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">PersonInterface</span><T>{<br> <span class="hljs-attr">name</span>:<span class="hljs-built_in">string</span>,<br> <span class="hljs-attr">age</span>:<span class="hljs-built_in">number</span>,<br> <span class="hljs-attr">extraInfo</span>:T<br>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">p</span>:<span class="hljs-title class_">PersonInterface</span><<span class="hljs-built_in">string</span>><br></code></pre></td></tr></table></figure>
<p>注:泛型接口本身也可以嵌套</p>
<h3 id="泛型类"><a href="#泛型类" class="headerlink" title="泛型类"></a>泛型类</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs ts"><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Person</span><T> {<br><span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>,</span><br><span class="hljs-params"><span class="hljs-keyword">public</span> <span class="hljs-attr">extraInfo</span>: T</span><br><span class="hljs-params"></span>) { }<br><span class="hljs-title function_">speak</span>(<span class="hljs-params"></span>) {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`我叫<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.name}</span>今年<span class="hljs-subst">${<span class="hljs-variable language_">this</span>.age}</span>岁了`</span>)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">extraInfo</span>)<br>}<br>}<br><span class="hljs-comment">// 测试代码1</span><br><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span><<span class="hljs-built_in">number</span>>(<span class="hljs-string">"tom"</span>, <span class="hljs-number">30</span>, <span class="hljs-number">250</span>);<br><span class="hljs-comment">// 测试代码2</span><br><span class="hljs-keyword">type</span> <span class="hljs-title class_">JobInfo</span> = {<br><span class="hljs-attr">title</span>: <span class="hljs-built_in">string</span>;<br><span class="hljs-attr">company</span>: <span class="hljs-built_in">string</span>;<br>}<br><span class="hljs-keyword">const</span> p2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span><<span class="hljs-title class_">JobInfo</span>>(<span class="hljs-string">"tom"</span>, <span class="hljs-number">30</span>, { <span class="hljs-attr">title</span>: <span class="hljs-string">'研发总监'</span>, <span class="hljs-attr">company</span>: <span class="hljs-string">'发发发</span><br><span class="hljs-string">科技公司'</span> });<br></code></pre></td></tr></table></figure>
<h3 id="泛型约束"><a href="#泛型约束" class="headerlink" title="泛型约束"></a>泛型约束</h3><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">LengthInterface</span> {<br><span class="hljs-attr">length</span>: <span class="hljs-built_in">number</span><br>}<br><span class="hljs-comment">// 约束规则是:传入的类型T必须具有 length 属性</span><br><span class="hljs-keyword">function</span> logPerson<T <span class="hljs-keyword">extends</span> <span class="hljs-title class_">LengthInterface</span>>(<span class="hljs-attr">data</span>: T): <span class="hljs-built_in">void</span> {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(data.<span class="hljs-property">length</span>)<br>}<br>logPerson<<span class="hljs-built_in">string</span>>(<span class="hljs-string">'hello'</span>)<br><span class="hljs-comment">// 报错:因为number不具备length属性</span><br><span class="hljs-comment">// logPerson<number>(100)</span><br></code></pre></td></tr></table></figure>
<h2 id="九-类型声明文件"><a href="#九-类型声明文件" class="headerlink" title="九.类型声明文件"></a>九.类型声明文件</h2><p>类型声明文件是 TypeScript 中的一种特殊文件,通常以.d.ts 作为扩展名。它的主要作用<br>是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使用这些 JavaScript 库<br>或模块时进行类型检查和提示。</p>
<p>在浏览器引入脚本时,注明类型<code>type:module</code></p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs ts"><span class="hljs-comment">// demo.js</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">add</span>(<span class="hljs-params">a, b</span>) {<br><span class="hljs-keyword">return</span> a + b;<br>}<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">mul</span>(<span class="hljs-params">a, b</span>) {<br><span class="hljs-keyword">return</span> a * b;<br>}<br></code></pre></td></tr></table></figure>
</div>
<hr>
<div>
<div class="post-metas my-3">
<div class="post-meta mr-3 d-flex align-items-center">
<i class="iconfont icon-category"></i>
<span class="category-chains">
<span class="category-chain">
<a href="/categories/frontend/" class="category-chain-item">frontend</a>
</span>
</span>
</div>
<div class="post-meta">
<i class="iconfont icon-tags"></i>
<a href="/tags/frontend/" class="print-no-link">#frontend</a>
<a href="/tags/typescript/" class="print-no-link">#typescript</a>
<a href="/tags/javascript/" class="print-no-link">#javascript</a>
<a href="/tags/typing/" class="print-no-link">#typing</a>
</div>
</div>
<div class="license-box my-3">
<div class="license-title">
<div>TypeScript学习笔记</div>
<div>http://arkpln.github.io/1251921997.html</div>