Loading... <div class="tip inlineBlock info">本文源自微信公众号:小生方勤</div> <div class="tip inlineBlock warning">本文是自动化发布的,如侵犯到了您的权益请联系博主删除。</div> <div class="rich_media_content " id="js_content"> <p style="display: none;" data-label="Power by:chajian.xiguaji.com"><br></p> <p style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(63, 63, 63);font-size: 16px;background-color: rgb(255, 255, 255);word-spacing: 2px;text-align: center;"><br></p> <section data-website="https://www.mdnice.com"> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">前言</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">JavaScript</code> 毋庸置疑是一门非常好的语言,但是其也有很多的弊端,其中不乏是作者设计之处留下的一些 “bug”。当然,瑕不掩瑜~</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">话说回来,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">JavaScript</code> 毕竟是一门弱类型语言,与强类型语言相比,其最大的编程陋习就是可能会造成我们类型思维的缺失(高级词汇,我从极客时间学到的)。而<strong style="color: rgb(53, 148, 247);">「思维方式决定了编程习惯,编程习惯奠定了工程质量,工程质量划定了能力边界」</strong>,而学习 Typescript,最重要的就是我们类型思维的重塑。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">那么其实,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Typescript</code> 在我个人理解,并不能算是一个编程语言,它只是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">JavaScript</code> 的一层壳。当然,我们完全可以将它作为一门语言去学习。网上有很多推荐 or 不推荐 Typescript 之类的文章这里我们不做任何讨论,学与不学,用或不用,利与弊。各自拿捏~</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">再说说 typescript(下文均用 ts 简称),其实对于 ts 相比大家已经不陌生了。更多关于 ts 入门文章和文档也是已经烂大街了。<strong style="color: rgb(53, 148, 247);">「此文不去翻译或者搬运各种 api或者教程章节。只是总结罗列和解惑,笔者在学习 ts 过程中曾疑惑的地方」</strong>。道不到的地方,欢迎大家评论区积极讨论。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">其实 Ts 的入门非常的简单:<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">.js</code> to <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">.ts</code>; over!</p> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplhJX7twJ7pO7H6TicNqicP5ib5dPMnHibvVaibo6VPIb3nta7M5qBkLq8HvQ/640?wx_fmt=png" data-type="png" data-w="198" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> </figure> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong style="color: rgb(53, 148, 247);">「但是为什么我都会写 ts 了,却看不懂别人的代码呢?」</strong> 这!就是入门与进阶之隔。也是本文的目的所在。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">首先推荐下 ts 的编译环境:typescriptlang.org</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">再推荐笔者收藏的几个网站:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> Typescript 中文网 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 深入理解 Typescript </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> TypeScript Handbook </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> TypeScript 精通指南 </section></li> </ul> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">下面,逐个难点梳理,逐个击破。</p> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">可索引类型</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">关于ts 的类型应该不用过多介绍了,<strong style="color: rgb(53, 148, 247);">「多用多记」</strong> 即可。介绍下关于 ts 的可索引类型。准确的说,这应该属于接口的一类范畴。说到接口(interface),我们都知道 <strong style="color: rgb(53, 148, 247);">「ts 的核心原则之一就是对值所具有的结构进行类型检查。」</strong> 它有时被称之为“鸭式辩型法”或“结构性子类型”。而接口就是其中的契约。可索引类型也是接口的一种表现形式,非常实用!</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface StringArray {<br> [index: number]: string;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">let</span> myArray: StringArray;<br>myArray = [<span style="color: #D69D85;line-height: 26px;">"Bob"</span>, <span style="color: #D69D85;line-height: 26px;">"Fred"</span>];<br><br><span style="color: #569CD6;line-height: 26px;">let</span> myStr: string = myArray[<span style="color: #B8D7A3;line-height: 26px;">0</span>];<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">上面例子里,我们定义了<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">StringArray</code>接口,它具有索引签名。这个索引签名表示了当用<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">number</code>去索引<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">StringArray</code>时会得到<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">string</code>类型的返回值。Typescript支持两种索引签名:字符串和数字。可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这是因为当使用<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">number</code>来索引时,JavaScript会将它转换成<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">string</code>然后再去索引对象。也就是说用100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">Animal</span> </span>{<br> name: string;<br>}<br><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">Dog</span> <span style="color: #569CD6;line-height: 26px;">extends</span> <span style="color: #DCDCDC;line-height: 26px;">Animal</span> </span>{<br> breed: string;<br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!</span><br>interface NotOkay {<br> [x: number]: Animal;<br> [x: string]: Dog;<br>}<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">下面的例子里,name的类型与字符串索引类型不匹配,所以类型检查器给出一个错误提示:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface NumberDictionary {<br> [index: string]: number;<br> length: number; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// 可以,length是number类型</span><br> name: string <span style="color: #57A64A;font-style: italic;line-height: 26px;">// 错误,`name`的类型与索引类型返回值的类型不匹配</span><br>}<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">当然,我们也可以将索引签名设置为只读,这样就可以防止给索引赋值</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface ReadonlyStringArray {<br> readonly [index: number]: string;<br>}<br><span style="color: #569CD6;line-height: 26px;">let</span> myArray: ReadonlyStringArray = [<span style="color: #D69D85;line-height: 26px;">"Alice"</span>, <span style="color: #D69D85;line-height: 26px;">"Bob"</span>];<br>myArray[<span style="color: #B8D7A3;line-height: 26px;">2</span>] = <span style="color: #D69D85;line-height: 26px;">"Mallory"</span>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// error!</span><br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">interface 和 type 关键字</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">stackoverflow 上的一个高赞回答还是非常赞的。typescript-interfaces-vs-types</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 和 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 两个关键字的含义和功能都非常的接近。这里我们罗列下这两个主要的区别:</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code>:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 同名的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 自动聚合,也可以跟同名的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code> 自动聚合 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 只能表示 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">object</code>、 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>、 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">function</code> 类型 </section></li> </ul> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code>:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 不仅仅能够表示 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">object</code>、 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>、 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">function</code> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 不能重名(自然不存在同名聚合了),扩展已有的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 需要创建新 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 支持复杂的类型操作 </section></li> </ul> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">举例说明下上面罗列的几点:</p> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Objects/Functions</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">都可以用来表示 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Object</code> 或者 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Function</code> ,只是语法上有些不同而已</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">interface</span> Point{<br> x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;<br> y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">interface</span> SetPoint{<br> (x:<span style="color: #4EC9B0;line-height: 26px;">number</span>,y:<span style="color: #4EC9B0;line-height: 26px;">number</span>):<span style="color: #4EC9B0;line-height: 26px;">void</span>;<br>}<br></code></pre> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> Point = {<br> x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;<br> y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">type</span> SetPoint = <span style="line-height: 26px;">(<span style="line-height: 26px;">x:<span style="color: #4EC9B0;line-height: 26px;">number</span>,y:<span style="color: #4EC9B0;line-height: 26px;">number</span></span>) =></span> <span style="color: #4EC9B0;line-height: 26px;">void</span>;<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>其他数据类型</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">与 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 不同,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 还可以用来标书其他的类型,比如基本数据类型、元素、并集等</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> Name = <span style="color: #4EC9B0;line-height: 26px;">string</span>;<br><br><span style="color: #569CD6;line-height: 26px;">type</span> PartialPointX = {x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br><span style="color: #569CD6;line-height: 26px;">type</span> PartialPointY = {y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br><br><span style="color: #569CD6;line-height: 26px;">type</span> PartialPoint = PartialPointX | PartialPointY;<br><br><span style="color: #569CD6;line-height: 26px;">type</span> Data = [<span style="color: #4EC9B0;line-height: 26px;">number</span>,<span style="color: #4EC9B0;line-height: 26px;">string</span>,<span style="color: #4EC9B0;line-height: 26px;">boolean</span>];<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Extend</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">都可以被继承,但是语法上会有些不同。另外需要注意的是,<strong style="color: rgb(53, 148, 247);">「interface 和 type 彼此并不互斥」</strong>。</p> <h4 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 14px;"><span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplDX9gZCddMMnAEdQFSlnw0ib24o8KAUCQQLt7Gq9y5CWwlp1HdHRcyvw/640?wx_fmt=png");display: inline-block;width: 16px;height: 16px;background-size: 16px;background-position: center center;background-repeat: no-repeat;margin-right: 6px;top: 5px;"></span>interface extends interface</span><span style="display: none;"></span></h4> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">interface</span> PartialPointX {x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br><span style="color: #569CD6;line-height: 26px;">interface</span> Point <span style="color: #569CD6;line-height: 26px;">extends</span> PartialPointX {y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br></code></pre> <h4 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 14px;"><span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplDX9gZCddMMnAEdQFSlnw0ib24o8KAUCQQLt7Gq9y5CWwlp1HdHRcyvw/640?wx_fmt=png");display: inline-block;width: 16px;height: 16px;background-size: 16px;background-position: center center;background-repeat: no-repeat;margin-right: 6px;top: 5px;"></span>type extends type</span><span style="display: none;"></span></h4> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> PartialPointX = {x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br><span style="color: #569CD6;line-height: 26px;">type</span> Point = PartialPointX & {y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br></code></pre> <h4 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 14px;"><span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplDX9gZCddMMnAEdQFSlnw0ib24o8KAUCQQLt7Gq9y5CWwlp1HdHRcyvw/640?wx_fmt=png");display: inline-block;width: 16px;height: 16px;background-size: 16px;background-position: center center;background-repeat: no-repeat;margin-right: 6px;top: 5px;"></span>interface extends type</span><span style="display: none;"></span></h4> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> PartialPointX = {x:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br><span style="color: #569CD6;line-height: 26px;">interface</span> Point <span style="color: #569CD6;line-height: 26px;">extends</span> PartialPointX {y:<span style="color: #4EC9B0;line-height: 26px;">number</span>;};<br></code></pre> <h4 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 14px;"><span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplDX9gZCddMMnAEdQFSlnw0ib24o8KAUCQQLt7Gq9y5CWwlp1HdHRcyvw/640?wx_fmt=png");display: inline-block;width: 16px;height: 16px;background-size: 16px;background-position: center center;background-repeat: no-repeat;margin-right: 6px;top: 5px;"></span>type extends interface</span><span style="display: none;"></span></h4> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface ParticalPointX = {<span style="color: #9CDCFE;line-height: 26px;">x</span>:number;};<br><br>type Point = ParticalPointX & {<span style="color: #9CDCFE;line-height: 26px;">y</span>:number};<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>implements</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">一个类,可以以完全相同的形式去实现<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 或者 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code>。但是,类和接口都被视为<span style="color: rgb(53, 148, 247);font-weight: bold;">静态蓝图(static blueprints)</span>,因此,他们不能实现/继承 联合类型的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code></p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface Point {<br> <span style="color: #9CDCFE;line-height: 26px;">x</span>: number;<br> y: number;<br>}<br><br><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">SomePoint</span> <span style="color: #DCDCDC;line-height: 26px;">implements</span> <span style="color: #DCDCDC;line-height: 26px;">Point</span> </span>{<br> x: <span style="color: #B8D7A3;line-height: 26px;">1</span>;<br> y: <span style="color: #B8D7A3;line-height: 26px;">2</span>;<br>}<br><br>type Point2 = {<br> <span style="color: #9CDCFE;line-height: 26px;">x</span>: number;<br> y: number;<br>};<br><br><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">SomePoint2</span> <span style="color: #DCDCDC;line-height: 26px;">implements</span> <span style="color: #DCDCDC;line-height: 26px;">Point2</span> </span>{<br> x: <span style="color: #B8D7A3;line-height: 26px;">1</span>;<br> y: <span style="color: #B8D7A3;line-height: 26px;">2</span>;<br>}<br><br>type PartialPoint = { <span style="color: #9CDCFE;line-height: 26px;">x</span>: number; } | { <span style="color: #9CDCFE;line-height: 26px;">y</span>: number; };<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// <span style="color: #608B4E;line-height: 26px;">FIXME:</span> can not implement a union type</span><br><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">SomePartialPoint</span> <span style="color: #DCDCDC;line-height: 26px;">implements</span> <span style="color: #DCDCDC;line-height: 26px;">PartialPoint</span> </span>{<br> x: <span style="color: #B8D7A3;line-height: 26px;">1</span>;<br> y: <span style="color: #B8D7A3;line-height: 26px;">2</span>;<br>}<br></code></pre> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplxTdvejPlrzHqdgHMJPAPEiaddfmKytXtibBPHp0Sn1rNWDagtApuMukQ/640?wx_fmt=png" data-type="png" data-w="897" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> </figure> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>声明合并</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">和 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 不同,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 可以被重复定义,并且会被自动聚合</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface Point {<span style="color: #9CDCFE;line-height: 26px;">x</span>:number;};<br>interface Point {<span style="color: #9CDCFE;line-height: 26px;">y</span>:number;};<br><br><span style="color: #569CD6;line-height: 26px;">const</span> point:Pint = {<span style="color: #9CDCFE;line-height: 26px;">x</span>:<span style="color: #B8D7A3;line-height: 26px;">1</span>,<span style="color: #9CDCFE;line-height: 26px;">y</span>:<span style="color: #B8D7A3;line-height: 26px;">2</span>};<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>only interface can</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在实际开发中,有的时候也会遇到 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code> 能够表达,但是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 做不到的情况:<strong style="color: rgb(53, 148, 247);">「给函数挂载属性」</strong></p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface FuncWithAttachment {<br> (param: string): boolean;<br> someProperty: number;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">const</span> testFunc: FuncWithAttachment = <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span>(<span style="line-height: 26px;">param: string</span>) </span>{<br> <span style="color: #569CD6;line-height: 26px;">return</span> param.indexOf(<span style="color: #D69D85;line-height: 26px;">"Neal"</span>) > <span style="color: #B8D7A3;line-height: 26px;">-1</span>;<br>};<br><span style="color: #569CD6;line-height: 26px;">const</span> result = testFunc(<span style="color: #D69D85;line-height: 26px;">"Nealyang"</span>); <span style="color: #57A64A;font-style: italic;line-height: 26px;">// 有类型提醒</span><br>testFunc.someProperty = <span style="color: #B8D7A3;line-height: 26px;">4</span>;<br></code></pre> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplZOib7csbOjHRC1ClAiaApWy8nQ3B6ubYoicKL6XKugKNgYMib2PsXDTicMg/640?wx_fmt=png" data-type="png" data-w="1041" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> </figure> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">& 和 | 操作符</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这里我们需要区分,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">|</code> 和 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">&</code> <span style="color: rgb(53, 148, 247);font-weight: bold;">并非位运算符</span>。我们可以理解为<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">&</code>表示必须同时满足所有的契约。<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">|</code>表示可以只满足一个契约。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface IA{<br> <span style="color: #9CDCFE;line-height: 26px;">a</span>:string;<br> b:string;<br>}<br><br>type TB{<br> <span style="color: #9CDCFE;line-height: 26px;">b</span>:number;<br> c:number [];<br>}<br><br>type TC = TA | TB;<span style="color: #57A64A;font-style: italic;line-height: 26px;">// TC 的 key,包含 ab 或者 bc 即可,当然,包含 bac 也可以</span><br>type TD = TA & TB;<span style="color: #57A64A;font-style: italic;line-height: 26px;">// TD 的 可以,必须包含 abc</span><br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">交叉类型</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">交叉类型,我们可以理解为合并。其实就是<strong style="color: rgb(53, 148, 247);">「将多个类型合并为一个类型」</strong>。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">Man & WoMan<br></code></pre> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 同时是 Man 和 Woman </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 同时拥有 Man 和 Woman 这两种类型的成员 </section></li> </ul> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface ObjectConstructor{<br> assign<T,U>(target:T,<span style="color: #9CDCFE;line-height: 26px;">source</span>:U):T & U;<br>}<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">以上是 ts 的源码实现,下面我们再看一个我们日常使用中的例子</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface A{<br> <span style="color: #9CDCFE;line-height: 26px;">name</span>:string;<br> age:number;<br> sayName:<span style="line-height: 26px;">(<span style="line-height: 26px;">name:string</span>)=></span><span style="color: #569CD6;line-height: 26px;">void</span><br>}<br><br>interface B{<br> <span style="color: #9CDCFE;line-height: 26px;">name</span>:string;<br> gender:string;<br> sayGender:<span style="line-height: 26px;">(<span style="line-height: 26px;">gender:string</span>)=></span><span style="color: #569CD6;line-height: 26px;">void</span><br>}<br><br><span style="color: #569CD6;line-height: 26px;">let</span> a:A&B;<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 这是合法的</span><br>a.age<br>a.sayGender<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">注意:16446</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">T & never = never<br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">extends</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">extends</code> 即为扩展、继承。在 ts 中,<strong style="color: rgb(53, 148, 247);">「extends 关键字既可以来扩展已有的类型,也可以对类型进行条件限定」</strong>。在扩展已有类型时,不可以进行类型冲突的覆盖操作。例如,基类型中键<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">a</code>为<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">string</code>,在扩展出的类型中无法将其改为<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">number</code>。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type num = {<br> <span style="color: #9CDCFE;line-height: 26px;">num</span>:number;<br>}<br><br>interface IStrNum extends num {<br> <span style="color: #9CDCFE;line-height: 26px;">str</span>:string;<br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 与上面等价</span><br>type TStrNum = A & {<br> <span style="color: #9CDCFE;line-height: 26px;">str</span>:string;<br>}<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在 ts 中,我们还可以通过条件类型进行一些三目操作:<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T extends U ? X : Y</code></p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type IsEqualType<A , B> = A extends B ? (B extends A ? <span style="color: #569CD6;line-height: 26px;">true</span> : <span style="color: #569CD6;line-height: 26px;">false</span>) : <span style="color: #569CD6;line-height: 26px;">false</span>;<br><br>type NumberEqualsToString = IsEqualType<number,string>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// false</span><br>type NumberEqualsToNumber = IsEqualType<number,number>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// true</span><br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">keyof</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong style="color: rgb(53, 148, 247);">「keyof 是索引类型操作符」</strong>。用于获取一个“常量”的类型,这里的“常量”是指任何可以在编译期确定的东西,例如<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">const</code>、<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">function</code>、<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>等。它是从 <strong style="color: rgb(53, 148, 247);">「实际运行代码」</strong> 通向 <strong style="color: rgb(53, 148, 247);">「类型系统」</strong> 的单行道。理论上,任何运行时的符号名想要为类型系统所用,都要加上 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">typeof</code>。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在使用<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>时,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>名表示实例类型,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">typeof class</code>表示 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code>本身类型。是的,这个关键字和 js 的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">typeof</code> 关键字重名了 。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">假设 T 是一个类型,那么<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">keyof T</code>产生的类型就是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 的属性名称字符串字面量类型构成的联合类型(联合类型比较简单,和交叉类型对立相似,这里就不做介绍了)。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong style="color: rgb(53, 148, 247);">「注意!上述的 T 是数据类型,并非数据本身」</strong>。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface IQZQD{<br> <span style="color: #9CDCFE;line-height: 26px;">cnName</span>:string;<br> age:number;<br> author:string;<br>}<br>type ant = keyof IQZQD;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">vscode</code> 上,我们可以看到 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">ts</code> 推断出来的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">ant</code>:</p> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplTyVcVDibrxniaF5rBCpsPQ1tIhbB32GMcCWAvZOWRvYFtrKk5rKv5eNw/640?wx_fmt=png" data-type="png" data-w="372" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> </figure> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">注意,如果 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 是带有字符串索引的类型,那么<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">keyof T</code>是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">string</code>或者<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">number</code>类型。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">索引签名参数类型必须为 "string" 或 "number"</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface <span style="color: #4EC9B0;line-height: 26px;">Map</span><T> {<br> [key: string]: T;<br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">//T[U]是索引访问操作符;U是一个属性名称。</span><br><span style="color: #569CD6;line-height: 26px;">let</span> keys: keyof <span style="color: #4EC9B0;line-height: 26px;">Map</span><number>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">//string | number</span><br><span style="color: #569CD6;line-height: 26px;">let</span> value: <span style="color: #4EC9B0;line-height: 26px;">Map</span><number>[<span style="color: #D69D85;line-height: 26px;">'antzone'</span>];<span style="color: #57A64A;font-style: italic;line-height: 26px;">//number</span><br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">泛型</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">泛型可能是对于前端同学来说理解起来有点困难的知识点了。通常我们说,泛型就是指定一个表示类型的变量,用它来代替某个实际的类型用于编程,而后再通过实际运行或推导的类型来对其进行替换,以达到一段使用泛型程序可以实际适应不同类型的目的。说白了,<strong style="color: rgb(53, 148, 247);">「泛型就是不预先确定的数据类型,具体的类型在使用的时候再确定的一种类型约束规范」</strong>。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">泛型可以应用于 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">function</code>、<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">interface</code>、<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">type</code> 或者 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">class</code> 中。但是注意,<strong style="color: rgb(53, 148, 247);">「泛型不能应用于类的静态成员」</strong></p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">几个简单的例子,先感受下泛型</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">log</span><<span style="line-height: 26px;">T</span>>(<span style="line-height: 26px;">value: T</span>): <span style="line-height: 26px;">T</span> </span>{<br> <span style="color: #4EC9B0;line-height: 26px;">console</span>.log(value);<br> <span style="color: #569CD6;line-height: 26px;">return</span> value;<br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 两种调用方式</span><br>log<string[]>([<span style="color: #D69D85;line-height: 26px;">'a'</span>, <span style="color: #D69D85;line-height: 26px;">',b'</span>, <span style="color: #D69D85;line-height: 26px;">'c'</span>])<br>log([<span style="color: #D69D85;line-height: 26px;">'a'</span>, <span style="color: #D69D85;line-height: 26px;">',b'</span>, <span style="color: #D69D85;line-height: 26px;">'c'</span>])<br>log(<span style="color: #D69D85;line-height: 26px;">'Nealyang'</span>)<br></code></pre> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 泛型类型、泛型接口 </section></li> </ul> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type Log = <T>(value: T) => T<br>let myLog: Log = log<br><br>interface Log<T> {<br> (value: T): T<br>}<br>let myLog: Log<number> = log // 泛型约束了整个接口,实现的时候必须指定类型。如果不指定类型,就在定义的之后指定一个默认的类型<br>myLog(1)<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong style="color: rgb(53, 148, 247);">「我们也可以把泛型变量理解为函数的参数,只不过是另一个维度的参数,是代表类型而不是代表值的参数。」</strong></p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #B8D7A3;line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">class</span> <span style="color: #DCDCDC;line-height: 26px;">Log</span><<span style="color: #DCDCDC;line-height: 26px;">T</span>> </span>{ <span style="color: #57A64A;font-style: italic;line-height: 26px;">// 泛型不能应用于类的静态成员</span><br> run(value: T) {<br> <span style="color: #4EC9B0;line-height: 26px;">console</span>.log(value)<br> <span style="color: #569CD6;line-height: 26px;">return</span> value<br> }<br>}<br><br><span style="color: #569CD6;line-height: 26px;">let</span> log1 = <span style="color: #569CD6;line-height: 26px;">new</span> Log<number>() <span style="color: #57A64A;font-style: italic;line-height: 26px;">//实例化的时候可以显示的传入泛型的类型</span><br>log1.run(<span style="color: #B8D7A3;line-height: 26px;">1</span>)<br><span style="color: #569CD6;line-height: 26px;">let</span> log2 = <span style="color: #569CD6;line-height: 26px;">new</span> Log()<br>log2.run({ <span style="color: #9CDCFE;line-height: 26px;">a</span>: <span style="color: #B8D7A3;line-height: 26px;">1</span> }) <span style="color: #57A64A;font-style: italic;line-height: 26px;">//也可以不传入类型参数,当不指定的时候,value 的值就可以是任意的值</span><br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">类型约束,需预定义一个接口</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface Length {<br> <span style="color: #9CDCFE;line-height: 26px;">length</span>: number<br>}<br><span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">logAdvance</span><<span style="line-height: 26px;">T</span> <span style="line-height: 26px;">extends</span> <span style="line-height: 26px;">Length</span>>(<span style="line-height: 26px;">value: T</span>): <span style="line-height: 26px;">T</span> </span>{<br> <span style="color: #4EC9B0;line-height: 26px;">console</span>.log(value, value.length);<br> <span style="color: #569CD6;line-height: 26px;">return</span> value;<br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 输入的参数不管是什么类型,都必须具有 length 属性</span><br>logAdvance([<span style="color: #B8D7A3;line-height: 26px;">1</span>])<br>logAdvance(<span style="color: #D69D85;line-height: 26px;">'123'</span>)<br>logAdvance({ <span style="color: #9CDCFE;line-height: 26px;">length</span>: <span style="color: #B8D7A3;line-height: 26px;">3</span> })<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">泛型的好处:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 函数和类可以轻松的支持多种类型,增强程序的扩展性 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 不必写多条函数重载,冗长的联合类型声明,增强代码的可读性 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 灵活控制类型之间的约束 </section></li> </ul> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">泛型,在 ts 内部也都是非常常用的,尤其是对于容器类非常常用。而对于我们,还是要多使用,多思考的,这样才会有更加深刻的体会。同时也对塑造我们类型思维非常的有帮助。</p> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>小试牛刀</span><span style="display: none;"></span></h3> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">pluck</span><<span style="line-height: 26px;">T</span>, <span style="line-height: 26px;">K</span> <span style="line-height: 26px;">extends</span> <span style="line-height: 26px;">keyof</span> <span style="line-height: 26px;">T</span>>(<span style="line-height: 26px;">o: T, names: K[]</span>): <span style="line-height: 26px;">T</span>[<span style="line-height: 26px;">K</span>][] </span>{<br> <span style="color: #569CD6;line-height: 26px;">return</span> names.map(<span style="line-height: 26px;"><span style="line-height: 26px;">n</span> =></span> o[n]);<br>}<br><br>interface Person {<br> <span style="color: #9CDCFE;line-height: 26px;">name</span>: string;<br> age: number;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">let</span> person: Person = {<br> <span style="color: #9CDCFE;line-height: 26px;">name</span>: <span style="color: #D69D85;line-height: 26px;">'Jarid'</span>,<br> <span style="color: #9CDCFE;line-height: 26px;">age</span>: <span style="color: #B8D7A3;line-height: 26px;">35</span><br>};<br><span style="color: #569CD6;line-height: 26px;">let</span> strings: string[] = pluck(person, [<span style="color: #D69D85;line-height: 26px;">'name'</span>, <span style="color: #D69D85;line-height: 26px;">'name'</span>, <span style="color: #D69D85;line-height: 26px;">'name'</span>]); <span style="color: #57A64A;font-style: italic;line-height: 26px;">//["Jarid", "Jarid", "Jarid"]</span><br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">所谓的小试牛刀,就是结合上面我们说的那几个点,分析下<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">pluck</code>方法的意思</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;"><T, K extends keyof T></code>约束了这是一个泛型函数 </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: square;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">keyof T</code> 就是取 T 中的所有的常量 key(这个例子的调用中),即为: <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">"name" | "age"</code> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K extends keyof Person</code> 即为 K 是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">"name"</code> or <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">"age"</code> </section></li> </ul> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 结合以上泛型解释,再看形参 </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: square;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K[]</code> 即为 只能包含 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">"name"</code> or <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">"age"</code>的数组 </section></li> </ul> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 再看返回值 </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: square;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T[K][]</code> 后面的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">[]</code>是数组的意思。而 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T[K]</code>就是去对象的 T 下的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">key</code>: <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K</code>的 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">value</code> </section></li> </ul> </ul> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">infer</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">infer 关键字最早出现在 PR 里面,<strong style="color: rgb(53, 148, 247);">「表示在 extends 条件语句中待推断的类型变量」</strong></p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">是在 ts2.8 引入的,在条件判断语句中,该关键字用于<strong style="color: rgb(53, 148, 247);">「替换手动获取类型」</strong>。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type PramType<T> = T extends (param : infer p) => any ? p : T;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在上面的条件语句中,<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">infer P</code> 表示待推断的函数参数,如果<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code>能赋值给<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">(param : infer p) => any</code>,则结果是<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">(param: infer P) => any</code>类型中的参数 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">P</code>,否则为<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code>.</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">interface INealyang{<br> <span style="color: #9CDCFE;line-height: 26px;">name</span>:<span style="color: #D69D85;line-height: 26px;">'Nealyang'</span>;<br> age:<span style="color: #D69D85;line-height: 26px;">'25'</span>;<br>}<br><br>type Func = <span style="line-height: 26px;">(<span style="line-height: 26px;">user:INealyang</span>) =></span> <span style="color: #569CD6;line-height: 26px;">void</span>;<br><br>type Param = ParamType<Func>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// Param = INealyang</span><br>type Test = ParamType<string>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// string</span><br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">工具泛型</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">所谓的工具泛型,其实就是泛型的一些语法糖的实现。完全也是可以自己的写的。我们也可以在<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">lib.d.ts</code>中找到他们的定义</p> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Partial</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Partial</code>的作用就是将传入的属性变为可选。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">由于 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">keyof</code> 关键字已经介绍了。其实就是可以用来取得一个对象接口的所有 key 值。在介绍 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Partial</code> 之前,我们再介绍下 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">in</code> 操作符:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type Keys = <span style="color: #D69D85;line-height: 26px;">"a"</span> | <span style="color: #D69D85;line-height: 26px;">"b"</span><br>type Obj = {<br> [p <span style="color: #569CD6;line-height: 26px;">in</span> Keys]: any<br>} <span style="color: #57A64A;font-style: italic;line-height: 26px;">// -> { a: any, b: any }</span><br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">然后再看 Partial 的实现:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type Partial<T> = { [P <span style="color: #569CD6;line-height: 26px;">in</span> keyof T]?: T[P] };<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">翻译一下就是<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">keyof T</code> 拿到 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 所有属性名, 然后 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">in</code> 进行遍历, 将值赋给 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">P</code>, 最后 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T[P]</code> 取得相应属性的值,然后配合<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">?:</code>改为可选。</p> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Required</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Required</code> 的作用是将传入的属性变为必选项, 源码如下</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type Required<T> = { [P <span style="color: #569CD6;line-height: 26px;">in</span> keyof T]-?: T[P] };<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Readonly</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">将传入的属性变为只读选项, 源码如下</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;">type Readonly<T> = { readonly [P <span style="color: #569CD6;line-height: 26px;">in</span> keyof T]: T[P] };<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Record</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">该类型可以将 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K</code> 中所有的属性的值转化为 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 类型,源码实现如下:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">/**<br> * Construct a type with a set of properties K of type T<br> */</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Record<K <span style="color: #569CD6;line-height: 26px;">extends</span> keyof <span style="color: #4EC9B0;line-height: 26px;">any</span>, T> = {<br> [P <span style="color: #569CD6;line-height: 26px;">in</span> K]: T;<br>};<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">可以根据 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K</code> 中的所有可能值来设置 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">key</code>,以及 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">value</code> 的类型,举个例子:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> T11 = Record<<span style="color: #D69D85;line-height: 26px;">'a'</span> | <span style="color: #D69D85;line-height: 26px;">'b'</span> | <span style="color: #D69D85;line-height: 26px;">'c'</span>, Person>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// -> { a: Person; b: Person; c: Person; }</span><br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Pick</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">从 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 中取出 一系列 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">K</code> 的属性</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">/**<br> * From T, pick a set of properties whose keys are in the union K<br> */</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Pick<T, K <span style="color: #569CD6;line-height: 26px;">extends</span> keyof T> = {<br> [P <span style="color: #569CD6;line-height: 26px;">in</span> K]: T[P];<br>};<br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Exclude</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">Exclude 将某个类型中属于另一个的类型移除掉。</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">/**<br> * Exclude from T those types that are assignable to U<br> */</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Exclude<T, U> = T <span style="color: #569CD6;line-height: 26px;">extends</span> U ? never : T;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">以上语句的意思就是 如果 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 能赋值给 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code> 类型的话,那么就会返回 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">never</code> 类型,否则返回 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code>,最终结果是将 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 中的某些属于 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code> 的类型移除掉</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">举个栗子:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> T00 = Exclude<<span style="color: #D69D85;line-height: 26px;">'a'</span> | <span style="color: #D69D85;line-height: 26px;">'b'</span> | <span style="color: #D69D85;line-height: 26px;">'c'</span> | <span style="color: #D69D85;line-height: 26px;">'d'</span>, <span style="color: #D69D85;line-height: 26px;">'a'</span> | <span style="color: #D69D85;line-height: 26px;">'c'</span> | <span style="color: #D69D85;line-height: 26px;">'f'</span>>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// -> 'b' | 'd'</span><br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">可以看到 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">'a' | 'b' | 'c' | 'd'</code> ,然后 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code> 是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">'a' | 'c' | 'f'</code> ,返回的新类型就可以将 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code> 中的类型给移除掉,也就是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">'b' | 'd'</code> 了。</p> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Extract</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Extract</code> 的作用是提取出 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 包含在 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code> 中的元素,换种更加贴近语义的说法就是从 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">T</code> 中提取出 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">U</code>,源码如下:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">/**<br> * Extract from T those types that are assignable to U<br> */</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Extract<T, U> = T <span style="color: #569CD6;line-height: 26px;">extends</span> U ? T : never;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">Demo:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">type</span> T01 = Extract<<span style="color: #D69D85;line-height: 26px;">'a'</span> | <span style="color: #D69D85;line-height: 26px;">'b'</span> | <span style="color: #D69D85;line-height: 26px;">'c'</span> | <span style="color: #D69D85;line-height: 26px;">'d'</span>, <span style="color: #D69D85;line-height: 26px;">'a'</span> | <span style="color: #D69D85;line-height: 26px;">'c'</span> | <span style="color: #D69D85;line-height: 26px;">'f'</span>>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// -> 'a' | 'c'</span><br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>Omit</span><span style="display: none;"></span></h3> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Pick</code> 和 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">Exclude</code> 进行组合, 实现忽略对象某些属性功能, 源码如下:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">/**<br> * Construct a type with the properties of T except for those in type K.<br> */</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Omit<T, K <span style="color: #569CD6;line-height: 26px;">extends</span> keyof <span style="color: #4EC9B0;line-height: 26px;">any</span>> = Pick<T, Exclude<keyof T, K>>;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">Demo:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 使用</span><br><span style="color: #569CD6;line-height: 26px;">type</span> Foo = Omit<{name: <span style="color: #4EC9B0;line-height: 26px;">string</span>, age: <span style="color: #4EC9B0;line-height: 26px;">number</span>}, <span style="color: #D69D85;line-height: 26px;">'name'</span>> <span style="color: #57A64A;font-style: italic;line-height: 26px;">// -> { age: number }</span><br></code></pre> <h3 style="color: black;font-weight: bold;text-align: center;margin-top: 50px;margin-bottom: 20px;"><span style="display: none;"></span><span style="border-bottom: 2px solid RGBA(79, 177, 249, .65);color: #595959;padding-bottom: 2px;"><span style="width: 30px;height: 30px;display: block;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplfXAoFibCnKfqYRkTQ3IyIJfF79SGwXVJtiau76hbooaZt2dKwTy681pA/640?wx_fmt=png");background-position: center center;background-size: 30px;left: 0px;right: 0px;margin: auto;opacity: 1;background-repeat: no-repeat;bottom: 12px;"></span>更多工具泛型</span><span style="display: none;"></span></h3> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplcZM6Qq5Hk4tpj3IBHGREtv03eetK2Fq09icTq6iaunTZ3P2Y2a88iaAvA/640?wx_fmt=png" data-type="png" data-w="2186" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> </figure> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">其实常用的工具泛型大概就是我上面介绍的几种。更多的工具泛型,可以通过查看 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">lib.es5.d.ts</code>里面查看。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">毕竟。。。搬运几段声明着实没啥意思。</p> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplEdaSA0ZicMV0MaLibqVoc98RsSMiaYL49sd5I33cgxaMqia3ibvW2MX5Rrg/640?wx_fmt=png" data-type="png" data-w="482" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> <figcaption style="margin-top: 5px;text-align: center;font-size: 13px;"> <span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplShuNZe2U1LQHuX1DmctGhuKkOGz7znbWF7BmrQfoPFcjDAficicrGibVg/640?wx_fmt=png");display: inline-block;width: 18px;height: 18px;background-size: 18px;background-repeat: no-repeat;background-position: center center;margin-right: 5px;margin-bottom: -5px;"></span>罗列 api 的写着也怪无聊的... </figcaption> </figure> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">类型断言</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">断言这种东西还是少用。。。。不多对于初学者,估计最快熟练掌握的就是类型断言了。毕竟 <strong style="color: rgb(53, 148, 247);">「any 大法好」</strong></p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">Typescript 允许我们覆盖它的推断(毕竟代码使我们自己写的),然后根据我们自定义的类型去分析它。这种机制,我们称之为 <strong style="color: rgb(53, 148, 247);">「类型断言」</strong></p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">const</span> nealyang = {};<br>nealyang.enName = <span style="color: #D69D85;line-height: 26px;">'Nealyang'</span>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// Error: 'enName' 属性不存在于 ‘{}’</span><br>nealyang.cnName = <span style="color: #D69D85;line-height: 26px;">'一凨'</span>; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// Error: 'cnName' 属性不存在于 '{}'</span><br></code></pre> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">interface</span> INealyang = {<br> enName:<span style="color: #4EC9B0;line-height: 26px;">string</span>;<br> cnName:<span style="color: #4EC9B0;line-height: 26px;">string</span>;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">const</span> nealyang = {} <span style="color: #569CD6;line-height: 26px;">as</span> INealyang; <span style="color: #57A64A;font-style: italic;line-height: 26px;">// const nealyang = <INealyang>{};</span><br>nealyang.enName = <span style="color: #D69D85;line-height: 26px;">'Nealyang'</span>;<br>nealyang.cnName = <span style="color: #D69D85;line-height: 26px;">'一凨'</span>;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">类型断言比较简单,其实就是“纠正”<code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">ts</code>对类型的判断,当然,是不是纠正就看你自己的了。</p> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">需要注意一下两点即可:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 推荐类型断言的预发使用 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;">as</code>关键字,而不是 <code style="margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 148, 247);background: rgba(59, 170, 250, 0.1);display: inline-block;padding-right: 2px;padding-left: 2px;border-radius: 2px;height: 21px;line-height: 22px;"><></code> ,防止歧义 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 类型断言并非类型转换,类型断言发生在编译阶段。类型转换发生在运行时 </section></li> </ul> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">函数重载</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <blockquote style="font-size: 0.9em;overflow: auto;padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;text-size-adjust: 100%;line-height: 1.55em;border-radius: 6px;color: rgb(89, 89, 89);box-sizing: inherit;border-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-color: rgba(64, 184, 250, 0.4);background: rgba(64, 184, 250, 0.1);"> <span style="color: RGBA(64, 184, 250, .5);font-size: 34px;line-height: 1;font-weight: 700;"></span> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 14px;word-spacing: 2px;line-height: 26px;">在我刚开始使用 ts 的时候,我一直困惑。。。为什么会有函数重载这么鸡肋的写法,可选参数它不香么?</p> <span style="float: right;color: RGBA(64, 184, 250, .5);"></span> </blockquote> <figure style="margin-top: 10px;margin-bottom: 10px;"> <img data-src="https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplIoze0N8f0J896MoYdAtTwdCfr4KkpPSkCZBbod9sqG1I9ZkVHlNceA/640?wx_fmt=png" data-type="png" data-w="197" style="width: auto;border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;"> <figcaption style="margin-top: 5px;text-align: center;font-size: 13px;"> <span style="background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplShuNZe2U1LQHuX1DmctGhuKkOGz7znbWF7BmrQfoPFcjDAficicrGibVg/640?wx_fmt=png");display: inline-block;width: 18px;height: 18px;background-size: 18px;background-repeat: no-repeat;background-position: center center;margin-right: 5px;margin-bottom: -5px;"></span>慢慢你品 </figcaption> </figure> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">函数重载的基本语法:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">declare</span> <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">test</span>(<span style="line-height: 26px;">a: <span style="color: #4EC9B0;line-height: 26px;">number</span></span>): <span style="line-height: 26px;">number</span></span>;<br><span style="color: #569CD6;line-height: 26px;">declare</span> <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">test</span>(<span style="line-height: 26px;">a: <span style="color: #4EC9B0;line-height: 26px;">string</span></span>): <span style="line-height: 26px;">string</span></span>;<br><br><span style="color: #569CD6;line-height: 26px;">const</span> resS = test(<span style="color: #D69D85;line-height: 26px;">'Hello World'</span>); <span style="color: #57A64A;font-style: italic;line-height: 26px;">// resS 被推断出类型为 string;</span><br><span style="color: #569CD6;line-height: 26px;">const</span> resN = test(<span style="color: #B8D7A3;line-height: 26px;">1234</span>); <span style="color: #57A64A;font-style: italic;line-height: 26px;">// resN 被推断出类型为 number;</span><br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这里我们申明了两次?!为什么我不能判断类型或者可选参数呢?后来我遇到这么一个场景,</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">interface</span> User {<br> name: <span style="color: #4EC9B0;line-height: 26px;">string</span>;<br> age: <span style="color: #4EC9B0;line-height: 26px;">number</span>;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">declare</span> <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">test</span>(<span style="line-height: 26px;">para: User | <span style="color: #4EC9B0;line-height: 26px;">number</span>, flag?: <span style="color: #4EC9B0;line-height: 26px;">boolean</span></span>): <span style="line-height: 26px;">number</span></span>;<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在这个 test 函数里,我们的本意可能是当传入参数 para 是 User 时,不传 flag,当传入 para 是 number 时,传入 flag。TypeScript 并不知道这些,当你传入 para 为 User 时,flag 同样允许你传入:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">const</span> user = {<br> name: <span style="color: #D69D85;line-height: 26px;">'Jack'</span>,<br> age: <span style="color: #B8D7A3;line-height: 26px;">666</span><br>}<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// 没有报错,但是与想法违背</span><br><span style="color: #569CD6;line-height: 26px;">const</span> res = test(user, <span style="color: #569CD6;line-height: 26px;">false</span>);<br></code></pre> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">使用函数重载能帮助我们实现:</p> <pre style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #1E1E1E;color: #DCDCDC;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;letter-spacing: 0px;"><span style="color: #569CD6;line-height: 26px;">interface</span> User {<br> name: <span style="color: #4EC9B0;line-height: 26px;">string</span>;<br> age: <span style="color: #4EC9B0;line-height: 26px;">number</span>;<br>}<br><br><span style="color: #569CD6;line-height: 26px;">declare</span> <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">test</span>(<span style="line-height: 26px;">para: User</span>): <span style="line-height: 26px;">number</span></span>;<br><span style="color: #569CD6;line-height: 26px;">declare</span> <span style="line-height: 26px;"><span style="color: #569CD6;line-height: 26px;">function</span> <span style="line-height: 26px;">test</span>(<span style="line-height: 26px;">para: <span style="color: #4EC9B0;line-height: 26px;">number</span>, flag: <span style="color: #4EC9B0;line-height: 26px;">boolean</span></span>): <span style="line-height: 26px;">number</span></span>;<br><br><span style="color: #569CD6;line-height: 26px;">const</span> user = {<br> name: <span style="color: #D69D85;line-height: 26px;">'Jack'</span>,<br> age: <span style="color: #B8D7A3;line-height: 26px;">666</span><br>};<br><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// bingo</span><br><span style="color: #57A64A;font-style: italic;line-height: 26px;">// Error: 参数不匹配</span><br><span style="color: #569CD6;line-height: 26px;">const</span> res = test(user, <span style="color: #569CD6;line-height: 26px;">false</span>);<br></code></pre> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">Ts 的一些实战</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">我之前在公众号里面发表过两篇关于TS在实战项目中的介绍:</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <a href="https://mp.weixin.qq.com/s?__biz=MzIxNjgwMDIzMA==&mid=2247484650&idx=1&sn=435a77e2b882a84e6c6026f7c3878031&scene=21#wechat_redirect" style="color: rgb(64, 184, 250);border-bottom: 1px solid rgb(59, 170, 250);" rel="nofollow" target="_blank">如何用 Decorator 装饰你的 Typescript?</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <a href="https://mp.weixin.qq.com/s?__biz=MzIxNjgwMDIzMA==&mid=2247485140&idx=1&sn=e056222bd4bcd4c7965219edb0fcd503&scene=21#wechat_redirect" style="color: rgb(64, 184, 250);border-bottom: 1px solid rgb(59, 170, 250);" rel="nofollow" target="_blank">一张页面引起的项目架构思考(rax+Typescript+hooks)</a> </section></li> </ul> <h2 style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 22px;border-bottom: 4px solid rgb(64, 184, 250);"><span style="display: flex;width: 20px;height: 20px;background-size: 20px 20px;background-image: url("https://mmbiz.qpic.cn/sz_mmbiz_png/udZl15qqib0PDF1OV4STY4HN2icIqrDiaplpEr9CDg27bQvt2Kwl7hZlHl338FO8t6Q5DtvkAhKrffjxIPfJkvOpA/640?wx_fmt=png");margin-bottom: -22px;"></span><span style="display: flex;color: #40B8FA;font-size: 20px;margin-left: 25px;">参考文献</span><span style="display: flex;width: 200px;height: 10px;border-top-left-radius: 20px;background: rgba(64, 184, 250, 0.5);color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;justify-content: flex-end;float: right;margin-top: -10px;"></span></h2> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-size: 15px;list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <a href="https://mp.weixin.qq.com/s?__biz=MzIxNjgwMDIzMA==&mid=2247485103&idx=1&sn=9063e21d824db34820e955967c5a8ea3&scene=21#wechat_redirect" style="color: rgb(64, 184, 250);border-bottom: 1px solid rgb(59, 170, 250);" rel="nofollow" target="_blank">未来可期的TypeScript</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> Typescript 中文文档 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 深入理解 Typescript </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> TypeScript 2.8下的终极React组件模式 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 【速查手册】TypeScript 高级类型 cheat sheet </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 高级类型 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> TypeScript 在 React 中使用总结 </section></li></ul><section data-id="94250" style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;white-space: normal;color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;text-align: left;background-color: rgb(255, 255, 255);border-width: 0px;border-style: none;border-color: initial;overflow-wrap: break-word !important;"><section data-id="91842" style="max-width: 100%;box-sizing: border-box;border-width: 0px;border-style: none;border-color: initial;text-align: right;overflow-wrap: break-word !important;"><section style="max-width: 100%;display: inline-block;clear: both;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section><section style="max-width: 100%;display: flex;justify-content: center;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> </section> </section> </section> </section> </section> </div> </div> Last modification:July 24th, 2020 at 10:55 am © 允许规范转载 Support 如果觉得我的文章对你有用,请随意赞赏 ×Close Appreciate the author Sweeping payments Pay by AliPay Pay by WeChat