<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>3R编码【3R教室 &amp; 3R工作室】 Blog</title>
        <link>https://3rcd.com/blog</link>
        <description>3R编码【3R教室 &amp; 3R工作室】 Blog</description>
        <lastBuildDate>Sat, 28 Feb 2026 10:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-Hans</language>
        <item>
            <title><![CDATA[3R教室简明介绍]]></title>
            <link>https://3rcd.com/blog/3r</link>
            <guid>https://3rcd.com/blog/3r</guid>
            <pubDate>Sat, 28 Feb 2026 10:00:00 GMT</pubDate>
            <description><![CDATA[[index]: / "首页"]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>更多有关3R教室的详细信息介绍请查看官网3R教室详细说明，地址: <a class="" href="https://3rcd.com/classroom/">3rcd.com/classroom</a></p>
</blockquote>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本介绍">📚基本介绍<a href="https://3rcd.com/blog/3r#%EF%BF%BD%EF%BF%BD%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%BB%8D" class="hash-link" aria-label="📚基本介绍的直接链接" title="📚基本介绍的直接链接" translate="no">​</a></h2>
<p><strong>3R教室是干什么的？</strong></p>
<p>3R教室是由站长 <code>@pincman</code> 于2022年8月10日创立的平克小站（pincman.com）转化而来，并在2023年3月正式更名为3R教室（域名更换为 <a class="" href="https://3rcd.com/">3rcd.com</a>）</p>
<p><strong>3R即：Remote Learn（远程学习）、Remote Work（远程工作）、Remote Profit（远程变现）</strong></p>
<p>在平克小站时期，一开始主要从事于node.js后端开发方面的教学，后续慢慢转变为nestjs+react的全栈开发训练营。而随着来自各行各业、国内外、大厂小厂、创业等各种领域不同年龄的会员规模的不断增长，我们获得了越来越多的资源，站长的知识面也在不断地增加。所以，随着时间的推移，3R教室慢慢开始扩展出一些新业务。另外，因为市场的日新月异，围绕着变现这一实用性主题，课程也慢慢变得更加多样化。目前，3R教室已经成为一个集教学、服务、资源、探讨与一体的，帮助程序员及其他行业的朋友实现远程自由职业者的闭环式的综合性付费远程社区。</p>
<p>教室最终目标是帮助码农朋友脱离996内卷以及长期处于高负荷打工和被优化的死循环，而实现慢生活状态！</p>
<p><strong>什么是远程自由职业？</strong></p>
<p><strong>简单来说，3R社区的远程自由职业包含以下两种类型</strong></p>
<ul>
<li class="">远程工作：虽是打工，但不用上班</li>
<li class="">个人创业：随着AI的快速发展，未来一人公司将会替代掉大量集中式的上班模式的打工人</li>
</ul>
<p>而个人创业又可以拆分为两种模式</p>
<ul>
<li class="">主动收入：例如远程软件订制（接单）工作室</li>
<li class="">被动收入：例如独立app开发销售、知识付费（卖课/付费咨询等）、付费站点运营等</li>
</ul>
<p><strong>目前提供哪些内容和服务？</strong></p>
<p>主要包含三部分内容：课程、服务、资源</p>
<p>其中课程有技术课和营销与营运等其他类型的课程组成，目前在做的以及将来要做的课程如下</p>
<ul>
<li class="">Nestjs最佳实践：早期课程</li>
<li class="">TS+AI全栈开发实战（即：全栈课）【<strong>当前主课程</strong>】：主要技术栈为react/next.js、node.js/hono.js、cicd/运维、AI开发工具使用、AI智能体开发等</li>
<li class="">远程自由职业指手册（即：变现课）【<strong>当前主课程</strong>】：非技术课程，包含远程工作求职、海外外包接单、被动收入和独立开发变现、工商税务、跨境收款、运营推广等技术变现相关的知识</li>
<li class="">3R兴趣课：未来新增课程，一系列站长喜欢的工具的使用教程的集合。比如wordpress建收费资源站、obsidian笔记使用、openclaw这种新兴工具使用等。后续会随着时代的发展不断增加新教程</li>
</ul>
<p>服务有以下几类</p>
<ul>
<li class=""><strong>技术课助教问答服务</strong></li>
<li class=""><strong>站长一对一会议</strong>：不限次数，可以是职业规划和技术方向指导、求职/职场/创业相关探讨、工具产品使用问答、服务运营和外包报价等各种方面的咨询，站长知无不言</li>
<li class=""><strong>社区会议</strong>：站长会经常性的开一些社区会议，由站长讲解一些自身的自由职业和创业经验，也会偶尔邀请一些在远程工作求职成功、有大厂/外企/海外工作顺利、创业或副业经营不错的其他会员同学作为嘉宾来分享一下他们的经验</li>
</ul>
<p>由于会员群体规模（近千人）的日益增长，加上我们是个费用较贵的社区，所以也在不断产生大量优质资源。当前大概包含以下资源</p>
<blockquote>
<p>根据资源的数量和对社区的贡献排序</p>
</blockquote>
<ul>
<li class=""><strong>3R工作室商业项目的共享</strong>：3R工作室是站长自营的一个远程外包团队，有早期的10来名会员构成。我们接下来很多海外或国内的商业外包，用课程相关的技术栈开发。部分项目经客户同意后把源码共享给教室会员。不断可以提供给会员朋友学习实战项目的机会，也可以供会员修改后作为自己的案例用于求职、接单等</li>
<li class=""><strong>远程/坐班工作的招聘和内推对接</strong>：3R教室中有很多会员在自主创业/海外创业等过程中需要为团队招聘远程开发者、海外工作中需要寻找代工、所在企业内部需要招聘内推同事、甚至还有一些职业HR付费进群招人的，所以这会产生大量的远程或坐班的内推岗位。而同时，教室社区内也有很多有求职需求的会员。这就形成了一个良好的资源对接平台。已经有许多会员直接在我们社区内部通过站长的对接招聘/求职成功</li>
<li class=""><strong>个人创业与融资对接</strong>：社区内有很多远程个人或小团队创业的会员朋友，也有很多手上有许多闲钱因为利息下降而想寻找一些优质项目进行小额投资的会员。这就实现了创业和天使投资之间的对接，目前3R教室已经有很多起这方面的成功案例</li>
<li class=""><strong>服务和作品推广</strong>：因为3R教室的所有会员均为付费会员，所以，有着良好的虚拟物品消费习惯。可以帮助从事独立开发、知识付费、付费资源等创业的朋友，在需要推广产品或服务时在社区内宣传，可以快速获得第一批启动用户</li>
<li class=""><strong>外包项目对接</strong>：我们群里也有很多朋友手上有一些外包资源，或者自主创业的会员朋友由于时间、对技术不感兴趣等原因想把项目交给其他会员做。但又不想提供长期固定发工资的远程工作岗位，而是愿意直接一锤子买卖。这时候就可以帮助想要接单的会员朋友在群内获得外包资源。不过这一块由于与我们3R工作室本身形成一定的竞争性，所以可能优质的资源会被3R工作室接下来。因此不要抱有太大希望😄。更好的方法是学习我们的变现课自行寻找客源</li>
</ul>
<p>以上基本涵盖了3R教室的所有内容，即：课程（技术和营销学习）＋服务（社区会议及问答、一对一等）+资源（商业项目、岗位/外包/投融对接、作品或服务推广等）。整体而言形成一个闭关路径</p>
<p>如下图</p>
<p><img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035606092.jpeg" alt="" class="img_SPwZ"></p>
<p><strong>购买会员后包就业、包有单子接、包回本吗？能免费先试试会员吗？求职或创业成功率大不大？</strong></p>
<ul>
<li class="">接单这块只提供方法和思路教学，其它别想，没单子分配给你</li>
<li class="">岗位也只是帮忙对接，不包就业，不是培训班。另外，回不了本，抱有这类需求的朋友不是这个社区的目标会员，请见谅！</li>
<li class="">不存在试用会员，试不了一点，并且购买后无法退款！</li>
<li class="">求职成功率还行，有求职需求的会员在本社区学习技术和求职方法后求职远程工作或坐班成功率（尤其远程工作）达到50%左右；创业我只提供方法，接单这块成功率还行，有自行接单的朋友（尤其全职的）成功率20-30%左右；纯创业的独立开发和被动收入的成功率纯看命，方法只是起辅助作用。如果纯创业都能高成功率，我自己早就不是赚一千个，是赚一个亿了，哈哈！</li>
</ul>
<p><strong>3R教室的会员费是多少？支持分期付款吗？能不能便宜点？能分开买单个课程或服务吗？</strong></p>
<p>4599元；不支持分期；便宜不了一点，但有时候会优惠期便宜一两百；不能，只有一种收费，即会员费</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="社区概况">🐳社区概况<a href="https://3rcd.com/blog/3r#%E7%A4%BE%E5%8C%BA%E6%A6%82%E5%86%B5" class="hash-link" aria-label="🐳社区概况的直接链接" title="🐳社区概况的直接链接" translate="no">​</a></h2>
<p><strong>3R教室当前拥有900+名会员</strong></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="群与资源">🦉群与资源<a href="https://3rcd.com/blog/3r#%E7%BE%A4%E4%B8%8E%E8%B5%84%E6%BA%90" class="hash-link" aria-label="🦉群与资源的直接链接" title="🦉群与资源的直接链接" translate="no">​</a></h3>
<p>3R教室最早使用飞书运营社区，后来又实用Discord。而目前使用最常用的微信和QQ来运营。在不久的将来，新官网上线后，官网等解决很多信息无法沉淀的问题。目前有以下群</p>
<p>其中</p>
<ul>
<li class="">两个微信会员总群用于日常交流和社区公告发布以及作品或服务推广等</li>
<li class="">海外会员微信群用于海外工作、留学、定居的会员之间的交流或内推</li>
<li class="">大厂与外企微信群用于在大厂或外企中工作的会员进行内推与职场交流</li>
<li class="">创业融资群用于投资人会员和创业会员之间的对接</li>
<li class="">岗位内推群用于远程或坐班的内推岗位发布和求职对接</li>
<li class="">金融投资探讨群用于日常投资、股票、虚拟币等非3R核心业务的探讨</li>
<li class="">会员QQ群用于技术课和变现课问答</li>
<li class="">【福利】有两个不需要会员资格就能进的外部群，一个外部微信交流群、一个外部QQ交流群，有需要进可以加客服微信【hidlthee_jia】或【newWorldSpace】拉一下。不过你需要给他们一个红包作为过路辛苦费😄。但是需要注意的是，外部群基本没啥人说话，会员资源（比如岗位等）也不会发到外部群。是纯交流群，有兴趣可以进一下</li>
</ul>
<p>目前最重要的是两个微信会员总群和一个会员QQ群</p>
<blockquote>
<p>截止编辑本文时（2026.1.21）微信群一已满，群二400多人。QQ群方面因为部分海外会员朋友没有QQ，或者非学习需求没进，所以只有800多人</p>
</blockquote>
<p><img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769019763539.png" alt="" class="img_SPwZ">
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769019782539.png" alt="" class="img_SPwZ">
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035588366.png" alt="" class="img_SPwZ"></p>
<p>目前所有资源的对接都在微信群内，不久的将来我们将会迁移到新官网中
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035579445.png" alt="" class="img_SPwZ">
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035619682.png" alt="" class="img_SPwZ"></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="课程相关">🦖课程相关<a href="https://3rcd.com/blog/3r#%E8%AF%BE%E7%A8%8B%E7%9B%B8%E5%85%B3" class="hash-link" aria-label="🦖课程相关的直接链接" title="🦖课程相关的直接链接" translate="no">​</a></h3>
<blockquote>
<p>详细课程内容介绍请查看<a class="" href="https://3rcd.com/classroom/">3R教室详情介绍</a></p>
</blockquote>
<blockquote>
<p>此处简短介绍，但内容更加新，官网固定三个月左右更新一次。尤其课程内容这块，官网可能比较过时（比如最近会新增很多AI开发工具的使用课程、PHP课程等），下文有说明，但官网不变。官网的变更需要一件事完全确认并且开工了才变更</p>
</blockquote>
<p>在技术课方面，课程的模式三年内进行了多次变更。一开始是直播上课模式，后来发现大家因为时间无法统一而变成视频录制的方式。然而，后来越来越多的会员其实是老码农转技术栈而并非都是零基础小白。所以，比较抵触视频类课程，更倾向于纯文档课程。并且视频类课程对编程学习的成长有害无益，尤其TS方面的技术栈。因为许多生态和框架都没有成熟的视频教程，需要自行查阅他们的官网文档学习。所以，在23年新版《nestjs最佳实践》开始，我就开始只做纯文档类技术课了。包括现在的《TS+AI全栈开发实战》也是纯文档课程。</p>
<p>不过纯文档课程，对零基础小白转码的朋友来说，并不友好，会极大地降低学习平滑度。所以，从26年开始，将会针对目前的《TS+AI全栈开发实战》和未来将要制作的PHP全栈、React Native+Electron客户端开发等课程，都加上一些难点小视频，并放在文档为主的课程内供基础差的同学快速入门</p>
<p><strong>另外，由于AI的快速发展，技术课将会在2026年开始新增许多使用AI进行自动辅助开发的内容。比如mcp、claude code+skills、antigravity等最新工具的使用、langchain+n8n的开发等</strong></p>
<p>变现课这块，一开始其实只是站长周末开个内部直播会议瞎聊聊的东西。后来发现，很多朋友本身技术不错或者对技术本来就不感冒，而更想学习这些会议经常聊到的远程工作求职方法、国内和海外的高价外包接单方法、独立app开发怎么卖，甚至是我怎么卖课卖起来的等等我个人过往做起来且做的不错的那些经历的经验，对这些更感兴趣。所以，后来慢慢我把这些会议给录制下来，放在网盘里供所有会员长期研究。这就是最初的变现课的由来。另外，一些我和外包客户的谈判记录、和其他会员一对一的会议记录等，在他们部分人同意的情况下，把这些录制视频也放到网盘里。所以，实际上变现课并不是一个正经的课程，而是以期刊制长期分享一些当下市场最好的变现方案及本人的一些变现经验的滚动式更新视频的集合。但是，由于目前视频太多了，全部查看很耗时间。所以，在2026年我将会把这些视频中的内容去粗取精重新录制一套完整的课程并且也长期期刊制更新，方便大家快速查询自己所感兴趣的内容，也就是即将开更的新的《远程自由职业实战》课程</p>
<p>目前所有技术课程主要放在一个线上的文档内，所有变现课程的视频都放在网盘内。后面将会融入新官网，方便会员朋友们浏览和学习
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035564205.png" alt="" class="img_SPwZ"></p>
<p>而技术课以及我们3R工作室共享的一些商业项目源码都放在自建的代码仓库中
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1769035443674.png" alt="" class="img_SPwZ"></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用方法">🛠使用方法<a href="https://3rcd.com/blog/3r#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95" class="hash-link" aria-label="🛠使用方法的直接链接" title="🛠使用方法的直接链接" translate="no">​</a></h2>
<blockquote>
<p>详细使用方法请查看3R教室的<a class="" href="https://3rcd.com/classroom/guide">指南页</a>（此处简短，但内容更加新，官网固定三个月左右更新一次）</p>
</blockquote>
<p>以下是简单地使用步骤</p>
<ol>
<li class="">查看<a class="" href="https://3rcd.com/classroom/">3R教室详情页</a>或查看本文档（官网介绍的缩减版）</li>
<li class="">如果没有疑问直接去<a class="" href="https://3rcd.com/classroom/">3R教室详情页</a> 滚动条拉到最底下扫描二维码购买会员（新版官网上线之后为下单购买，目前仍然扫码购买）。如果有疑问可以咨询客服微信【hidlthee_jia】或【newWorldSpace】（或扫码<a title="首页" class="" href="https://3rcd.com/">首页</a>左侧工具栏的公众号/关注is3rcd）</li>
<li class="">购买会员后加站长微信【iampincman】</li>
<li class="">拉微信群和QQ群，默认只拉会员总群二、QQ会员群。如果需要进其他群（比如求职进微信内推群、海外生活和工作或留学等可以进海外群、高学历朋友需要被内推进大厂及外企可以进大厂与外企群），可以让客服或者站长拉一下</li>
<li class="">如果是以学习为目的购买会员的朋友，无论学习技术还是运营，刚购买后都可以先和站长一对一一次，以便事半功倍的学习课程并更好地实现自己的目标（特别说明，站长一对一是不限次数的，后续有疑问可以随时联系站长一对一）</li>
<li class="">学以致用，在边学习的同时，可以边实现你的目标，比如求职、接单、独立app开发销售等</li>
<li class="">如果是招聘、投资、融资、推广等需要的会员，可以联系站长帮忙发布信息和对接</li>
</ol>]]></content:encoded>
            <category>3R教室</category>
            <category>3R社区</category>
            <category>全栈开发</category>
            <category>TS全栈</category>
            <category>远程工作</category>
            <category>远程变现</category>
            <category>独立开发</category>
            <category>知识付费</category>
            <category>创投对接</category>
            <category>海外外包</category>
            <category>职业生规划</category>
        </item>
        <item>
            <title><![CDATA[3R社区合作方一栏【所有会员购买合作方产品或服务享有优惠】]]></title>
            <link>https://3rcd.com/blog/partners</link>
            <guid>https://3rcd.com/blog/partners</guid>
            <pubDate>Tue, 30 Sep 2025 08:32:31 GMT</pubDate>
            <description><![CDATA[以下是3R社区和3R教室的合作方提供的产品或服务。所有3R会员购买这些产品或服务享有优惠（联系站长@pincman获取优惠码）]]></description>
            <content:encoded><![CDATA[<p>以下是3R社区和3R教室的合作方提供的产品或服务。所有3R会员购买这些产品或服务享有优惠（联系站长<code>@pincman</code>获取优惠码）</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="-牛油果英语训练营">🗽 牛油果英语训练营<a href="https://3rcd.com/blog/partners#-%E7%89%9B%E6%B2%B9%E6%9E%9C%E8%8B%B1%E8%AF%AD%E8%AE%AD%E7%BB%83%E8%90%A5" class="hash-link" aria-label="🗽 牛油果英语训练营的直接��链接" title="🗽 牛油果英语训练营的直接链接" translate="no">​</a></h2>
<p>一个由3R会员<code>@慧敏</code>同学运营的职场英语教学训练营</p>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>详情查看<a href="https://flowus.cn/3rcd/share/7de2754f-6493-48c6-9e48-e2552d4fb048?code=VYW62" target="_blank" rel="noopener noreferrer" class="">官方介绍</a>。优惠策略：原价<del>999元</del>，3R会员享<code>799元</code></p></div></div>
<p>慧敏同学介绍：早期3R会员，哈工大毕业，雅思7.5+，目前在西班牙定居和工作
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/2025-09-30/1759192561-496588-image.png" alt="" class="img_SPwZ"></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="欧欧全球收款解决方案">🌎欧欧全球收款解决方案<a href="https://3rcd.com/blog/partners#%E6%AC%A7%E6%AC%A7%E5%85%A8%E7%90%83%E6%94%B6%E6%AC%BE%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88" class="hash-link" aria-label="🌎欧欧全球收款解决方案的直接链接" title="🌎欧欧全球收款解决方案的直接链接" translate="no">​</a></h2>
<p>一个由3R会员<code>@opacity</code>同学运营的全球收款和跨境电商运营手册，同时提供帮忙手动开通服务
:::
详情查看<a href="https://www.setupyourpay.com/" target="_blank" rel="noopener noreferrer" class="">官方介绍</a>。优惠策略：原价<del>59美刀</del>，3R会员享<code>$49</code>
:::
欧欧(opacity)同学介绍：最早的一批3R会员，曾是3R工作室开发主力，目前在某创业企业任技术总监
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/2025-09-30/1759192662-664868-image.png" alt="" class="img_SPwZ"></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="️bbk职场咨询与java教学">☕️bbk职场咨询与java教学<a href="https://3rcd.com/blog/partners#%EF%B8%8Fbbk%E8%81%8C%E5%9C%BA%E5%92%A8%E8%AF%A2%E4%B8%8Ejava%E6%95%99%E5%AD%A6" class="hash-link" aria-label="☕️bbk职场咨询与java教学的直接链接" title="☕️bbk职场咨询与java教学的直接链接" translate="no">​</a></h2>
<p>一个由3R会员<code>@勇敢的心bbk</code>同学提供的IT职场咨询和java教学社区</p>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>详情查看<a href="https://docs.qq.com/doc/DUVJGdEFMZnFmakxO" target="_blank" rel="noopener noreferrer" class="">官方介绍</a>。优惠策略：原价<del>199元</del>，3R会员享<code>168元</code></p></div></div>
<p>勇敢的心bbk同学介绍：3R会员，目前运营一个200+的付费职场咨询和java教学社区
<img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/2025-09-30/1759193005-963630-image.png" alt="" class="img_SPwZ"></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="iovz云主机">💻iovz云主机<a href="https://3rcd.com/blog/partners#iovz%E4%BA%91%E4%B8%BB%E6%9C%BA" class="hash-link" aria-label="💻iovz云主机的直接链接" title="💻iovz云主机的直接链接" translate="no">​</a></h2>
<p>iovz长期为3R社区免费提供服务器助力。具有亚洲/欧美快速线路、免备案、高性价比等特性</p>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>详情查看<a href="https://www.iovz.com/" target="_blank" rel="noopener noreferrer" class="">官方介绍</a>。优惠策略：所有主机和服务器享六折</p></div></div>
<p><img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media/1759193553857.png" alt="" class="img_SPwZ"></p>]]></content:encoded>
            <category>3R教室</category>
            <category>3R社区</category>
            <category>全球收款</category>
            <category>java培训</category>
            <category>职场咨询</category>
            <category>英语教学</category>
            <category>英语培训</category>
            <category>职场英语</category>
        </item>
        <item>
            <title><![CDATA[关于站长]]></title>
            <link>https://3rcd.com/blog/about</link>
            <guid>https://3rcd.com/blog/about</guid>
            <pubDate>Tue, 16 Jan 2024 23:00:52 GMT</pubDate>
            <description><![CDATA[[classroom]: /classroom]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>更新于2023年5月，可能你看到这个页面时，很多介绍看起来比较老(因为我在日新月异的发展^v^)，后续有时间更新吧...</p></div></div>
<div class="theme-admonition theme-admonition-success admonition_M1T2 alert alert--success"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>success</div><div class="admonitionContent_ndgZ"><p>有项目需求请查看<a class="" href="https://3rcd.com/workroom">3R工作室</a>，需要购买会员请查看<a class="" href="https://3rcd.com/classroom">3R教室</a></p></div></div>
<p>我是<a href="https://3rcd.com/" target="_blank" rel="noopener noreferrer" class="">3R编码</a>及<a href="https://3rku.com/" target="_blank" rel="noopener noreferrer" class="">3R社区</a>的站长，也是<a class="" href="https://3rcd.com/classroom">3r教室</a>与<a class="" href="https://3rcd.com/workroom">3R工作室</a>的创始人 —— pincman <br>我是一名生长在江南水乡(南浔古镇)、成长于江南水乡(绍兴古城)的88年老码农！ <br>
我热爱生活和Money，喜爱电影/乐器、昆曲/戏曲、写作/文学/书法/绘画、历史/天文/神秘科学等一切有意思的东西。曾经梦想成为一名文艺青年(或者作家?)，但岁月逐渐把我变成了一名长期从事编码工作但又爱搞点营销和折腾的"江湖人"。现在，是一名不折不扣的自由工作者/小微创业者(混日子专业户)，同时梦想成为一名终生编码者！</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="️自我介绍">🙋‍♂️自我介绍<a href="https://3rcd.com/blog/about#%EF%B8%8F%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D" class="hash-link" aria-label="🙋‍♂️自我介绍的直接链接" title="🙋‍♂️自我介绍的直接链接" translate="no">​</a></h2>
<p>07 年开始接触的编程，一开始接触的是Delphi，开发过当年比较热门的远控软件。
后来从 08-16 年一直从事 PHP 的 Web 项目以及云计算方面的开发，期间主要使用 Jquery，CI，Laravel，Symfony，Bootstrap 的技术。
17 年开始专注于 Typescript + React + Node.js + Rust 的编码工作，目前正在学习 Golang</p>
<p>目前主要工作是运营<a class="" href="https://3rcd.com/classroom">3r教室</a>与<a class="" href="https://3rcd.com/workroom">3R工作室</a>。因为自从做了这个官网稀里糊涂做到现在😅，貌似已经收入超过了打工一辈子所得了，所以应该还是会永久的继续自由工作下去...</p>
<p>经常逛这些网站：🌐<a href="https://3rcd.com/" target="_blank" rel="noopener noreferrer" class="">3R编码</a>、🌐<a href="https://3rku.com/" target="_blank" rel="noopener noreferrer" class="">3R酷</a>、🌐<a href="https://space.bilibili.com/53679018" target="_blank" rel="noopener noreferrer" class="">哔哩哔哩</a>、🌐<a href="https://www.zhihu.com/people/pincman" target="_blank" rel="noopener noreferrer" class="">知乎</a>、🌐<a href="https://www.youtube.com/@pincman8682" target="_blank" rel="noopener noreferrer" class="">youtube</a>、🌐<a href="https://google.com/" target="_blank" rel="noopener noreferrer" class="">谷歌</a>、🌐<a href="https://github.com/pincman" target="_blank" rel="noopener noreferrer" class="">github</a>、🌐<a href="https://stackoverflow.com/" target="_blank" rel="noopener noreferrer" class="">stackoverflow</a>、🌐<a href="https://douban.com/" target="_blank" rel="noopener noreferrer" class="">豆瓣</a>...
以下只是展示一些站长个人擅长以及正在学习中的技术栈，与<a class="" href="https://3rcd.com/workroom">3R工作室</a>团队或者<a class="" href="https://3rcd.com/classroom">3R教室</a>无关</p>
<ul>
<li class="">运维全家桶： Linux，Docker，K8S，CICD，Mysql，Mongodb，Redis，RabbitMQ 等</li>
<li class="">CSS全家桶：TailwindCSS，Shadcn/ui，Antd，Arco Design，Mui，Bootstrap 等</li>
<li class="">React全家桶： Vite，Webpack，React，React Native，React Router，React Query，React-DND，Mobx，Zustand，Nextjs，Taro，GraphQL 等</li>
<li class="">Node全家桶： Bun，Electron，hono.js，Fastify，Nestjs，Typeorm，Prisma，Yargs，Cluster，PM2 等</li>
<li class="">PHP全家桶： PHP，Laravel，Symfony，Workerman，wordpress 等</li>
<li class="">其它比较擅长：Delphi、Haskell、Perl</li>
<li class="">比较熟悉（也就是只能二开或改改）：Vue.js，Nuxtjs、Python、Rust</li>
<li class="">正在学习：Golang</li>
</ul>
<p>同时站长也胜任：品牌形象设计，Logo 设计，原型设计，视频剪辑，电脑/手机组装修理等工作</p>
<p>站长用过或正在用以下工具
MacOS，VScode，Ecmas，PHPStorm，Sketch，OmniGraffle.Xmind，Navicat，Redis Manager，Typora，Obsidian，PicGo，Mweb，AI，PS，Final cut pro，Motion，PR，AE，Screenflow，Camtasia，Wordpress，Magento，Hexo，Docusaurus，NextCloud，Gitea，Drone，Oneinstack，Openstack，Discuz 等等</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="联系方式">📱联系方式<a href="https://3rcd.com/blog/about#%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F" class="hash-link" aria-label="📱联系方式的直接链接" title="📱联系方式的直接链接" translate="no">​</a></h3>
<p>由于站长长年为自己996工作中，但常年有 <strong>“我是某某大厂程序员，会XXX技术，有外包吗？”</strong> 又或者 <strong>“帮我我找份远程工作”</strong> 等等这类抽象网友的加微信骚扰，所以站长把微信放到其它页面中了...你可以在<a class="" href="https://3rcd.com/classroom">3R教室</a>中找到我的微信，如果有外包需求可以查看<a class="" href="https://3rcd.com/workroom">3R工作室</a>介绍或直接通过<a class="" href="https://3rcd.com/classroom/members">教室成员页</a>联系客户经理，给您造成不便表示抱歉，望谅解😄</p>
<p>但也可以通过以下方式找我</p>
<ul>
<li class="">💬电报号：<code>@pincman1988</code> (不保证一定在线)</li>
<li class="">📮邮箱: <code>pincman@qq.com</code> 或者 <code>pincman1988@gmail.com</code></li>
</ul>
<p>也欢迎通过<strong>点击页面上的工具栏</strong>关注我的社交账户哦！👏</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="接单工作">🔭接单工作<a href="https://3rcd.com/blog/about#%E6%8E%A5%E5%8D%95%E5%B7%A5%E4%BD%9C" class="hash-link" aria-label="🔭接单工作的直接链接" title="🔭接单工作的直接链接" translate="no">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p><del>目前在职的是一份北美的TS全栈开发远程工作，业余时间从事知识付费和在线教学工作，同时也承接志趣相投，价格合理的外包项目</del><br>
目前已经有一个由3R教室早期成员组成的强大且专业的远程外包团队-<a class="" href="https://3rcd.com/workroom">3R工作室</a>，所以我自己不开发外包了，有外包开发需求的客户朋友请查看<a class="" href="https://3rcd.com/workroom">3R工作室</a></p></div></div>
<p>📣3R工作可以做的: 从产品的原型设计，形象设计，宣传视频，使用文档，到全平台（Macos，Windows，web，ssr，安卓，IOS，各类小程序）的编码开发，测试，构建部署，性能优化，SEO优化等</p>
<ul>
<li class="">👉 本人接单不爱扯皮，价格和周期合适即可，442 付款</li>
<li class="">👉 客户发需求，客户或本人报价，确认合作后先付 4 成订金</li>
<li class="">👉 项目中期再付 4 成</li>
<li class="">👉 上线或交付源码后付尾款，第一年免费维护，第二年维护费另谈</li>
<li class="">👉 请自行制作原型设计稿或也可以由我推荐设计师(只负责推荐不负责参与设计)，没有设计稿或不愿意做设计稿的包不接</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="教室工作">🍵教室工作<a href="https://3rcd.com/blog/about#%E6%95%99%E5%AE%A4%E5%B7%A5%E4%BD%9C" class="hash-link" aria-label="🍵教室工作的直接链接" title="🍵教室工作的直接链接" translate="no">​</a></h2>
<p>因为 Typescript，React，Node 等技术体系在国内外都不是很卷，并且薪资也不错，使用范围广，语法友好等优点成为站长最爱的技术体系。所以本站以 Linux + Typescript + React + Node + 服务器运维与CICD 这个技术栈为主线来进行教学，成为这个技术栈中的一名布道者</p>
<p>以下 Typescript 或者说 <a href="https://es6.ruanyifeng.com/" target="_blank" rel="noopener noreferrer" class="">ES6+</a> 能做的事（几乎无所不能）：</p>
<ul>
<li class="">🍋 使用 Electron 可以直接开发桌面应用</li>
<li class="">🍋 使用 React + 各种UI库可以开发中后台</li>
<li class="">🍋 使用 Nextjs + Tailwind 可以开发任何类型的服务端渲染的网站</li>
<li class="">🍋 使用 Taro 可以开发各种跨平台小程序</li>
<li class="">🍋 使用 React Native 可以开发跨设备移动APP</li>
<li class="">🍋 使用 Fastify 可以开发轻量级API</li>
<li class="">🍋 使用 Nestjs 可以开发高性能的企业级后端</li>
<li class="">🍋 使用 Yargs 可以构建命令工具</li>
<li class="">🍋 使用 Docusaurus 可以构建知识分享网站</li>
<li class="">🍋 使用 Gatsbyjs 可以构建企业官网</li>
<li class="">🍋 使用 ThreeJS 可以构建3D世界</li>
<li class="">🍋 还有 AI，嵌入式等等的库在日新月异的增加</li>
</ul>
<p>最让人感到兴奋的是，这套全栈开发的技能国外基本属于主流，类似于国内的 Spring Boot 和 Vue，但是因为不内卷的缘故，远程工作非常好找，薪资也比较可观，<strong>这个目前本人就在做</strong>。并且除此外，国内企业目前招聘岗位也很多，竞争力却不大，也很好找工作。最有价值的是，因为全栈开发，所以甚至可以直接脱离 996 的地狱模式，成为一名真正的自由职业者或独立开发者😄。</p>
<p>同时，为了会员同学有一个更好的技术变现前景。除了TS全栈开发的技术课外，站长还通过自己远程自由职业十几年的经验为基石，制作了一套掘金课以及同时提供一对一服务。
此课程主要涉及</p>
<ul>
<li class="">🍋 海外(以及国内)远程外包项目接单渠道拓展和客户洽谈方法</li>
<li class="">🍋 知识付费、应用/系统/作品等售卖、平台经营盈利等被动收入的推广和圈粉方案</li>
<li class="">🍋 远程工作求职指导及职业规划</li>
</ul>
<p>当然站长认为 React + Node 全栈开发也是有一些不足的，但是一些瑕不掩瑜的不足可以忽略，比如 React Native 性能对比 Flutter 会差一些等，这些问题是没多大影响的，没必要再去学个 Flutter，除非你自己有兴趣和空余时间。但是有一些还是比较致命的问题，比如 Node 在某些 CPU 密集型或者高并发处理时的表现实在差强人意，对于一些高要求应用显然无法达标，这时候你还可以自学一个简单但非常实用的编程语言 - Go。
Golang 作为对 TS 体系中 Node 后端的补足还是非常优秀的，尤其是在构建微服务和处理高性能需求方面很出色。</p>
<p>另外，学习TS全栈开发虽然天花板比较高，但这是个长期的过程。如果中间需要快速找一些技术变现的渠道，那么可以学习一下wordpress、<a href="https://strapi.io/" target="_blank" rel="noopener noreferrer" class="">strapi</a>等，这些课程也在我们后续的计划之内。也可以先学习<a class="" href="https://3rcd.com/classroom">课程</a>的《变现篇》，通过外包差价来实现一部分变现！</p>
<p>出于以上的所有原因，站长搭建了这个由 Docusaurus 编写的网站，用于分享和布道 Linux + Typescript + React + Node + 服务器运维与CICD 全栈开发的技能。</p>
<p>通过制作视频，编写文档，提供问答服务，开放工作室商业项目源码学习来开始 <a class="" href="https://3rcd.com/classroom">3R教室</a> 等全方位探讨与教学，为同学们节省宝贵的学习时间用于干你想干的事</p>
<p>希望大家多多关注本站，关注我的B站或知乎号，站长会很快的更新和制作新的教程，谢谢各位同学的支持。</p>
<p>By the way</p>
<p><em>想搭建一个像小站一样的站点来吗？使用本站开发的 RowFish 开源主题立即可架设一个属于你自己的小站，并可通过知识分享平台引流，通过知识付费或产品出售以及接单盈利！</em></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RowFish -- 开源一款比较好看的docusaurus主题]]></title>
            <link>https://3rcd.com/blog/rowfish</link>
            <guid>https://3rcd.com/blog/rowfish</guid>
            <pubDate>Tue, 16 Jan 2024 23:00:52 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[3R教室诞生的故事]]></title>
            <link>https://3rcd.com/blog/story</link>
            <guid>https://3rcd.com/blog/story</guid>
            <pubDate>Tue, 16 Jan 2024 23:00:52 GMT</pubDate>
            <description><![CDATA[[3r]: /classroom]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-danger admonition_M1T2 alert alert--danger"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>危险</div><div class="admonitionContent_ndgZ"><p>🔔 注意此文撰写时间较久远，部分内容已过时，详细介绍请直接查看<a class="" href="https://3rcd.com/classroom">3R教室</a>页面</p></div></div>
<p>你是否正在遭遇这些困难或需求？那么加入<a class="" href="https://3rcd.com/classroom">3R教室</a>正是时候</p>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>点<a class="" href="https://3rcd.com/classroom">此处</a>查看更多关于3R教室的知识点等信息以及报名方法</p></div></div>
<p><img decoding="async" loading="lazy" src="https://cn-nb1.rains3.com/3rcd/media202210141956488.png" alt="" class="img_SPwZ"></p>
<p>接下来一起来了解一下<a class="" href="https://3rcd.com/classroom">3R教室</a>诞生的故事吧</p>
<p>原贴地址: <a href="https://eleduck.com/posts/ARfak9" target="_blank" rel="noopener noreferrer" class="">https://eleduck.com/posts/ARfak9</a></p>
<blockquote>
<p>这并不是故事，是我的亲生经历，分享出来的初衷是疑义相与析，希望能为大家打开打工外的更多的思路</p>
</blockquote>
<p>从在电鸭上发布<a href="https://eleduck.com/posts/qzfXdK" target="_blank" rel="noopener noreferrer" class="">第一篇帖子</a>开始，眨眼3个多月过去，从一开始的教培小白慢慢成长为大白😂，说说那些有趣和心酸的事儿。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="山重水复">🌓山重水复<a href="https://3rcd.com/blog/story#%E5%B1%B1%E9%87%8D%E6%B0%B4%E5%A4%8D" class="hash-link" aria-label="🌓山重水复的直接链接" title="🌓山重水复的直接链接" translate="no">​</a></h2>
<p>原本和朋友合伙经营一家小微软件公司，作为技术合伙人(其实也没啥技术含量)，2019年的疫情一来，公司的客户都自身难保，类似于网络和软件这类基本都不续费了，然后就一直走下坡路。因为个人以前开发过一款不可言说的软件，业余搞点外快，不过看着做了六七年的公司快倒闭了，实在不忍心就把自己开发的软件抛售了，然而还是杯水车薪，公司还是从15人变成10人，变成5人，最后就剩我两个光杆司令，然后又坚持了一年左右就解散了，不过产品卖了撑了一段时间。。。</p>
<p>吃了几年年老本，今年实在扛不住了就打算去找找工作试试。然而三四线城市大家都懂，尤其是浙江的三四线城市，因为疫情和经济双重打击，就剩这么少得可怜的几家外包公司，而且有两家是那种租了个民房，成天梦想上市的企业网站和小程序开发工作室，连社保都不打算给，薪资低的出奇，还需要单休，没道理可讲啊😅，再加上小城市基本都是后端java，前端vue，两者都不是我擅长的，还需要跟一帮应届生去卷几千一月感觉实在划不来，并且虽说是小型私企，老板都架子特别大，受不鸟</p>
<p>眼看快过金三银四了，赶紧放弃58(因为年纪太大，88年的，其它的APP知道的不多)，登录BOSS，刷着刷着，刷到了一家萧山在招聘的企业，一看Typescript,React,Node,Nestjs,会PHP更佳等等关键字，再一看薪资35k，直接眼冒金光，立马联系，结果去了两次面试和笔试，还真成了。然后就开开心心去上班啦，虽然每天来去累一点，但好在离湖州老家和居住地绍兴都比较近，来去也方便，比去深圳找工作靠谱很多。充满干劲就是上，然后做了一个月，到了发工资了，老板说款项没到，拖一拖。我想晚几天就晚几天呗，然后直接给晚跑路了，发了个红包给我表示抱歉，整个人直接差点晕过去😭</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="仙人指路">✨仙人指路<a href="https://3rcd.com/blog/story#%E4%BB%99%E4%BA%BA%E6%8C%87%E8%B7%AF" class="hash-link" aria-label="✨仙人指路的直接链接" title="✨仙人指路的直接链接" translate="no">​</a></h2>
<p>从5月开始一直到7月初每天焦虑失眠就没睡过个整觉。实在找不到工作，然后就做了点视频教程放B站，然后做了个个人网站，再把原来的项目升级升级，重新整整放github上，到处发发，想弄点点赞，弄点star，想这样会不会求职起来会更方便，如果能顺带赚几个零花钱就更好了😋。诶，实在是无可奈何。后来因为一个开源项目建了个QQ群，在其它QQ群宣传，拉来20几个人，然后聊到失业问题，群里有个网友说我这个技术栈比较适合远程工作，可以去电鸭看看。出于好奇心理，打开了电鸭，同时也打开了我的未来。</p>
<p>第一眼看到电鸭这个社区映入眼帘的是一大片招聘信息，点进去几个发觉都是远程工作，然后就知乎一搜"什么是远程工作"，"远程办公是否靠谱"等关键字，发现这种模式正适合我这种情况--当时老婆二胎孕晚期在家无法出远门，背上一大堆房贷等债务，本地三线小城市又找不到合适技术栈的工作，寻思着能做个远程的临时工作先赚点钱也不错。然后电鸭上提交了一份简历，不过迟迟没人来联系，感觉应该希望渺茫。</p>
<p>这时候想起多年前的一个网站-v2ex，好像也有看到过远程工作相关的帖子，于是乎就去上面发了一贴。没想到真有人来找我了，然后面试笔试都是一气呵成的一次性过，就开始抱着做做看的态度先试试。薪资比较低，才15k，还包含了折现的社保，而且是私人小外包公司，诶，家里事多，是真的懒得去搞。。。</p>
<p>后来又去电鸭逛逛，正好看到一个node+php的职位在招聘，20多k，立马点开联系方式，是一家台湾的公司，当然因为技术栈比较符合，也是面试笔试一下就比较流畅地进去了。这家公司各方面相对来说是比较正规的公司了，甚至五险一金都会找当地财务给代缴，这么优质的工作，当然立马有干劲啦，哈哈(至今还和他家联系着，帮他们内推一些同学)。但是做了没多久，我家二宝要出来了，实在忙不过来，因为以前一直自己合伙创业，没啥这方面的经验，所以没有协商，干脆选择了暂时辞职，也是非常抱歉的说。但是公司还是很客气的，做了没几天，薪资是按全职的薪资算给我的。</p>
<p>后面家里的事情处理完毕，又开始找工作了，不过这时对远程办公方面已经有一定经验了，知道的平台也有好几个，这次选择了领英的一个TS全栈开发的职位，是一家多伦多的华人公司(后续来说，枫叶国对我个人来说，真是块幸运之地，虽然没去过，哈哈)，同样顺利地通过了笔试面试。并且薪资开出了税后32k，也是可以在国内代缴五险一金等社保，而且14薪的。因为PM是歪果仁，所以前面工作非常累，每次都是PM说话，我录制语音，接着有道翻译，最后整理出中文文字版，原本955的工作硬生生被我自己搞到996，后来换了个华人PM，再加上Notion的熟练，事情就变得简单许多了。因为工作效率还可以，业余时间就是开始想着搞点外快，想来想去不知道搞啥，想过做跨境电商卖家乡的丝绸，童装，婚纱之类，也想过写写小说，做做电影解说等等。。。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="柳暗花明">🐳柳暗花明<a href="https://3rcd.com/blog/story#%E6%9F%B3%E6%9A%97%E8%8A%B1%E6%98%8E" class="hash-link" aria-label="🐳柳暗花明的直接链接" title="🐳柳暗花明的直接链接" translate="no">​</a></h2>
<p>还是后来一位群友(也是3R教室的第二期同学)给我打开了思路，看来还是得有群👏。那天正在群里讨论大家都在哪边工作，我说了，找了份远程工作，那位同学就好奇，远程还能工作，怎么工作的。然后我一一介绍了一下，他瞬间来了兴趣，因为国内比较卷，经济又不行，这位兄弟工作一直996，然后天天担心被裁，所以就去尝试找一找远程工作。因为他是spring+vue全栈开发，这在国内是主流，然而远程工作一般都是海外的，用这套的并不比其他技术栈多，但是竞争却异常激烈，所以就没下文了。但是他给我打开了思路，我在想，我本身用TS+React+Node.js/Nestjs这套技术求职远程多份都很顺利，能不能同样地把这套技术交给一些感兴趣的同学，然后这些同学可以去尝试求职远程办公呢？后来因为在电鸭发了个露脸帖子，有个新西兰的外包需求找到我了，同样也是指定用这套技术，于是顺利接单了。后面那个加拿大的老板可能看我比较空吧，时不时给点额外的外包给我做，甚至直接把客户推给我，然后类似的外包单子也越来越多，一个人根本接不下来，但是有钱不赚那不是onebadie嘛😛，然后又想着，如果教一些同学，让他们业余做点兼职帮我做外包，自己赚个差价呢？</p>
<p>于是立即头脑风暴一下，再加上原本做视频教程积累了一帮粉丝，于是就开始想装一回B啦。在自己的网站上加了个3R教室的栏目，提供所谓3R服务(Remote Learn,Remote Work,Remote Order)，远程TS全栈开发学习，远程工作求职指导，远程外包任务分配的闭环服务。</p>
<p>一开始抱着玩玩的心态，收费3700，尝试在自己的群里问了一下，直接来了7位同学报名，这效果连我自己都惊呆啦，清楚地记得那天是2022年8月10号。不过说实话，第一期来报名的同学大多只冲着学习TS全栈来的，对远程工作和外包的兴趣并不大。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="向死求生">🌱向死求生<a href="https://3rcd.com/blog/story#%E5%90%91%E6%AD%BB%E6%B1%82%E7%94%9F" class="hash-link" aria-label="🌱向死求生的直接链接" title="🌱向死求生的直接链接" translate="no">​</a></h2>
<p>9月份的时候，第二期打算尝试招一批专门喜欢整个3R思维的同学来报名，然后就在v2ex，电鸭，知乎等社区发帖，同时勤快地更新B站视频，然后第二期又来了9位同学报名，第二期跟第一期不一样的地方在于，来报名的都是来自世界各地的华人，有台湾的，有美国的等等，后面两期这个现象越来越明显，海外学员占比越来越多。其实这时已经有些忙不过来了，因为同一时间外包也多了起来。这时要经营下去，只能选择辞职，要么不再招第三期，一二期教完，只当玩一场。当然后来毅然选择了辞职，因为人嘛，有时候是要有点梦想，实现梦想有时候是需要冒险的。但是等到9月底第三期开始，还不知道哪里去招生，因为该发的社区全发过了，老发广告贴应该会适得其反。。。不过天不厌一个有梦想并为此付出实践的人，因为这时一位新加坡的同学救活了3R，成为了3R教室的长期合作伙伴，开始帮我招生了(前面一直在我的群里发些他们公司的招聘信息)。三期微信群和Learnku社区两个地方也来了好几位同学，结果他帮忙一推，本来打算10人的三期变成了25人，同样的第四期各种搜索引擎，社区再加上那位新加坡的同学推荐过来的订阅者和3R同学加起来近30人。目前新加坡合作的朋友，其他同学推荐，搜索引擎，微信群等学生来源已经占据主流，希望后续慢慢地可以完全脱离社区发帖吧。目前(截止2022年12月3号)3R教室的成果是 订阅者 7人，学员70人，有来自大陆，台湾，瑞典，新加坡，美国，加拿大，澳大利亚等世界各地的同学，短短3个多月尽我所能也算是做了一份能力范围内的事业吧。</p>
<p>同时外包方面，也是遇到一位比较合得来的丹麦(现已居杭州)朋友，专门帮忙介绍客户过来，并且还为3R教室注入了一大笔个人启动资金，也长期为3R教室提供一些远程岗位。此外也有一位来自加拿大的朋友，长期提供外包项目，同时还有社区找过来的新西兰，台湾，美国等多个地区的客户，甚至前期Boss直聘也带来一位非常高质量的客户，大多数客户都非常专业，提供详细设计图和需求文档，部分非专业IT公司的传统行业客户也会另外找人做好，并且全部严格按照442方式微信转账及直接打银行卡付款，大多数外包在稳步推进，部分已经完结或即将完结。因为外包比较多，大部分分配出去给学员兼职做，已经渐渐形成闭环。</p>
<p>对于远程工作方面，目前有多个方面来提供远程岗位，首先是帮我推荐学生的新加坡朋友，他固定提供长期的高端TS全栈(React/Nextjs/Nestjs/Deno/Rust等等)远程岗位，其次是丹麦的投资人，固定长期提供React+PHP/Rails方面的中低端远程岗位，另外还有前面的台湾老东家，偶尔也会提供一些React,React Native方面的远程岗位，以及我自己长期提供外包兼职机会，目前来说岗位并不是很多，也不丰富，但是毕竟刚刚起步，需要走的路还是非常远的，我要做的并不是包就业的培训班，内推只是其中3R免费附加的一项服务，并不是重点，专门提供远程岗位也不是3R理念中应该做的，3R要做的最重要的是指导同学学好这套技术栈去合适的平台寻找合适自己的工作，<strong>比如电鸭，领英这些专业的远程岗位提供平台</strong>。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="后事之师">🍀后事之师<a href="https://3rcd.com/blog/story#%E5%90%8E%E4%BA%8B%E4%B9%8B%E5%B8%88" class="hash-link" aria-label="🍀后事之师的直接链接" title="🍀后事之师的直接链接" translate="no">​</a></h2>
<p>各位同学对目前的大环境多多少少有些了解，因为经济下滑，目前国内IT环境是非常内卷的，尤其是 Vue，Java，Python 等在国内非常流行的技术，被卷到白菜价，同时由于疫情影响导致线下工作多多少少会比较麻烦，加上一线城市的高额生活成本以及长期加班无法兼顾家庭和生活，这也倒逼我们这些中低端码农需要做一些改变来Get到新的机会，并拓展自己的思维从而提升收入，实现自由。</p>
<p>于此同时，一些海外发达国家的劳务用工费用高得出奇，非常想用其它国家或地区的IT人来降低运营成本。然而大多数需要远程工作人员的企业或外包需求者所要求的技术栈与国内大多数坐班企业的要求是不一样的。对于求职者和接单者来说使用国内的热门技术（Java、PHP、Vue之类）去寻找远程机会时，得到反馈少之又少，就算偶尔有一个一般也会瞬间被卷走。反之 TS、React、Node.js、Go 等新兴技能甚至 Ruby 之类国内无人问津的技术却在各种远程工作Offer和外包需求中持续刷榜，尤其以TS全栈开发为甚，远程工作机会极少会遇到国内高校和培训班里教的最多的 Java，Vue 等。</p>
<p>就以本人自己的工作经历为例子对国内外远程全职工作和外包做一个对比吧</p>
<p><strong>全职工作对比</strong></p>
<table><thead><tr><th style="text-align:center"></th><th style="text-align:center">本地公司坐班</th><th style="text-align:center">内陆公司远程</th><th style="text-align:center">亚太地区公司远程</th><th style="text-align:center">海外公司远程</th></tr></thead><tbody><tr><td style="text-align:center">前端技术栈</td><td style="text-align:center">jQuery/Vue</td><td style="text-align:center">React/Vue</td><td style="text-align:center">React + TS</td><td style="text-align:center">Angular</td></tr><tr><td style="text-align:center">后端技术栈</td><td style="text-align:center">Spring全家桶</td><td style="text-align:center">PHP</td><td style="text-align:center">Node.js<br></td><td style="text-align:center">Node.js<br>Rust</td></tr><tr><td style="text-align:center">工作时间</td><td style="text-align:center">996</td><td style="text-align:center">8x5 小时<br>双休<br>基本无加班</td><td style="text-align:center">8x5 小时<br>双休<br>偶尔加班</td><td style="text-align:center">(6/8)x5 小时<br>双休<br>无加班</td></tr><tr><td style="text-align:center">薪资水准</td><td style="text-align:center">19k(税后12薪)</td><td style="text-align:center">20k(税后12薪)</td><td style="text-align:center">25k(税后13薪)</td><td style="text-align:center">35k(税前14薪)</td></tr><tr><td style="text-align:center">福利与社保</td><td style="text-align:center">五险</td><td style="text-align:center">五险一金(折现)</td><td style="text-align:center">五险一金(代缴)</td><td style="text-align:center">五险一金(代缴)</td></tr><tr><td style="text-align:center">信誉和稳定性</td><td style="text-align:center">十分稳定<br>适合长期<br>但容易被优化</td><td style="text-align:center">稳定性一般<br>容易拖欠<br>容易单方面解约<br>适合短线</td><td style="text-align:center">比较稳定<br>可以做两年</td><td style="text-align:center">非常稳定<br>适合长期<br>不会被优化</td></tr><tr><td style="text-align:center">最大的缺点</td><td style="text-align:center">容易过劳猝死</td><td style="text-align:center">类外包，很难进步</td><td style="text-align:center">需要实时找到人<br>自由度较低</td><td style="text-align:center">偶尔需要英语交流<br>口语不佳入职后很累<br></td></tr><tr><td style="text-align:center">最大的优点</td><td style="text-align:center">稳定<br>晋升机会大<br>容易拓展人脉(其实没啥卵用)</td><td style="text-align:center">时间和空间自由<br>(类似于外包)<br>内容简单<br>可以利用业余时间赚外快</td><td style="text-align:center">时间和自由度<br>介于远程和坐班之间<br>薪资介于国内与欧美之间<br>平衡之选择</td><td style="text-align:center">时间和空间都比较自由<br>薪资比较高<br>(基本与一线中小厂齐平)<br></td></tr><tr><td style="text-align:center">体验企业</td><td style="text-align:center">私营小厂/外包公司</td><td style="text-align:center">小团队/私营创业者</td><td style="text-align:center">业务流成熟的中型企业</td><td style="text-align:center">某行业独角兽</td></tr><tr><td style="text-align:center">体验行业</td><td style="text-align:center">SAAS与低代码</td><td style="text-align:center">跨境电商</td><td style="text-align:center">酒店旅游</td><td style="text-align:center">办公协作软件</td></tr><tr><td style="text-align:center">综合时长</td><td style="text-align:center">13年</td><td style="text-align:center">5个月</td><td style="text-align:center">30天</td><td style="text-align:center">30天</td></tr><tr><td style="text-align:center">评分建议</td><td style="text-align:center">⭐️⭐️⭐️</td><td style="text-align:center">⭐️</td><td style="text-align:center">⭐️⭐️⭐️⭐️</td><td style="text-align:center">⭐️⭐️⭐️⭐️⭐️</td></tr></tbody></table>
<p><strong>本地和远程外包对比</strong></p>
<p>下面对本人创业以来承接并完成的外包单子做一下对比</p>
<table><thead><tr><th style="text-align:center"></th><th style="text-align:center">本土外包</th><th style="text-align:center">内陆远程外包</th><th style="text-align:center">海外远程外包</th></tr></thead><tbody><tr><td style="text-align:center">主技术栈</td><td style="text-align:center">基本无要求</td><td style="text-align:center">Vue，PHP，WordPress，Laravel 为主(少部分 .Net)</td><td style="text-align:center">React，node.js 为主(少部分PHP)</td></tr><tr><td style="text-align:center">项目</td><td style="text-align:center">易连客计件APP(设计费拖欠)<br>天使迎地板网二开(二期款拖欠)<br>鲁生古钱币交易网(已推掉)<br>黑白板纺织客APP(尾款拖欠)</td><td style="text-align:center">诺思医疗器材网(即将完结👍)<br> 海森丝CRM(设计费拖欠)<br>未来人轻纺小程序(二期款拖欠)<br>M星人少儿编程APP(已完结👍)<br></td><td style="text-align:center">新西兰音乐桌面软件: Lubolu(已完结👍)<br>一个不愿透露的台湾购物网站(已完结👍)<br>美国购物平台: GoFlashDeals(即将完结👍)<br>加拿大校园社交平台<!-- -->:Youni<!-- -->(开发中👍)<br>法国长期外包合作商: 电商网站(即将开启第一次合作)</td></tr><tr><td style="text-align:center">付款</td><td style="text-align:center">全部需要公司资质<br>全部非常扯皮<br>全部需要签署法律合同<br>37方式支付，风险极大<br>部分以交朋友名义让免费做<br>二期款与尾款拖时间不支付</td><td style="text-align:center">部分付钱非常爽快<br>部分无需企业资质<br>部分需要对公账户<br>部分无需签署合同<br>部分会远程442付款</td><td style="text-align:center">全部付款非常爽快<br>全部无需企业资质<br>大部分无需签合同<br>少部分签署简易合同即可<br>全部直接转账付款442付款</td></tr><tr><td style="text-align:center">难度</td><td style="text-align:center">客户一般以一个月开发一个天猫为主</td><td style="text-align:center">难度较低，一般无复杂度</td><td style="text-align:center">难度及复杂度较高</td></tr><tr><td style="text-align:center">客户</td><td style="text-align:center">啥都要</td><td style="text-align:center">非常在意设计<br>一般对并发，架构与技术栈无感</td><td style="text-align:center">设计和原型一般客户自带<br>一般会有固定技术栈需求 <br>非常在意架构 Devops，TDD，E2E<br>以及代码质量、注释和API文档</td></tr><tr><td style="text-align:center">预算</td><td style="text-align:center">猪八戒、淘宝价或者免费</td><td style="text-align:center">0-5w</td><td style="text-align:center">3.6w-12.3w</td></tr><tr><td style="text-align:center">渠道</td><td style="text-align:center">58同城和本地网站发一下就有</td><td style="text-align:center">接单非常不稳定，看运气</td><td style="text-align:center">接单渠道很多，比较稳定</td></tr><tr><td style="text-align:center">特点</td><td style="text-align:center">乙方毫无任何体验，建议别接</td><td style="text-align:center">项目难度较低<br>对并发和架构基本无感<br>一般对设计比较在意<br>部分客户非常扯皮<br>容易拖欠风险极大</td><td style="text-align:center">比较在意性能与架构以及前端动效<br>拿单容易，渠道方便利润较高<br>项目一般会比较大，以W为单位计算<br>几乎所有客户自带设计<br></td></tr><tr><td style="text-align:center">评分</td><td style="text-align:center">~</td><td style="text-align:center">看运气(⭐️⭐️-⭐️⭐️⭐️⭐️⭐️)</td><td style="text-align:center">⭐️⭐️⭐️⭐️⭐️</td></tr></tbody></table>
<p>站长给出的建议是，学习好TS全栈开发，然后开始找第一份远程工作，习惯并体验一下，不要想第一次就找长期高薪的，适应一段时间后慢慢选择更好的。同时远程工作虽然多了很多自由和陪家人的时间，不过也同时失去了社交，所以在工作的同时十分建议大家去维护好社交圈，因为总有一天你会有做不动的时候，在这之前你需要有一份自己的事业。我这里建议大家在周末的时候多接一些海外的远程外包做做，尽量承接一些简单不影响工作又可以拓展人脉的单子，这对以后是非常有用的。尤其在外包比较多的时候直接尝试自由职业也是一种不错的选择，这也是站长目前在做的。</p>
<p>另外对于远程招聘和发包者来说，我们拥有规范的开发流程与包含各种技术栈的稳定团队，不仅有兼职者，同时也有处于自由职业状态，随时可以全职的同学，我们的协作模式可以参考<a class="" href="https://3rcd.com/classroom"><strong>3R教室</strong></a>。</p>
<p>到目前为止(进行到第五期)，整个3R闭环已经形成，我也有了自己的小团队(由一二期的部分同学和订阅者组成)，后面期待随着业务的扩大，能有更多的长期合作外包客户加入，有更多热爱学习技术的同学加入，有更多需要这项技术栈的远程岗位提供者加入，一起把3R这个理念推广开来，让更多的人习惯于远程学习，远程工作，远程自由接单，更高的收入，更好的生活，干自己更感兴趣的事。期待你的加入，报名3R教室请点 <a class="" href="https://3rcd.com/classroom"><strong>此处</strong></a></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="有关收益">🌾有关收益<a href="https://3rcd.com/blog/story#%E6%9C%89%E5%85%B3%E6%94%B6%E7%9B%8A" class="hash-link" aria-label="🌾有关收益的直接链接" title="🌾有关收益的直接链接" translate="no">​</a></h2>
<p>收益的确是每个月都在增长，差不多相当于打工的2-2.5倍左右，但是付出更多的是汗水，需要备课，周末教学，独立做外包，或者对分配给学生的外包把控项目进度，客户需求跟进，帮人招聘到处挖人，帮人求职时对简历，项目的包装以及求职指导等等。不过相信这一切都是值得的，也希望3R会帮到越来越多的人</p>
<p>============================== 更新 ==============================</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="更新">🌵更新<a href="https://3rcd.com/blog/story#%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="🌵更新的直接链接" title="🌵更新的直接链接" translate="no">​</a></h2>
<p>自从上一次发文之后，又过了好长一段时间了，3R教室已经运转140，转眼就是元旦，祝大家新年快乐！💐💐💐</p>
<p>现在3R教室已经有快100位同学，感谢电鸭，感谢Learnku，感谢谷歌！</p>
<p>新年伊始，我们3R的讲课模式和课程内容也开始全面升级，进行了一次大翻新，期望能让更多的同学更好地学习和接受知识。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="讲课模式">🎓讲课模式<a href="https://3rcd.com/blog/story#%E8%AE%B2%E8%AF%BE%E6%A8%A1%E5%BC%8F" class="hash-link" aria-label="🎓讲课模式的直接链接" title="🎓讲课模式的直接链接" translate="no">​</a></h3>
<p>因为原来直播+录制模式导致课程时长过长。很多海外的同学又有时差，无法跟进直播，只能去看录制，而过长的直播时长，很多无用的聊天和废话使许多海外或者没时间上课的同学在看录制时不断地需要拉进度条，甚至放弃视频直接看文档为主了，所以新课改为录制剪辑好的视频直接发送来替代原来的直播模式。这样做会有许多优点</p>
<ul>
<li class="">
<p>同学们可以随时随地的学习，而不受时间束缚，就算报名后突然没有时间，也可以过段时间再学习，视频也能跟着最新的技术栈更新，后续用到某个技术点的时候拿出来复习即可。而原来的方式，每一期的直播教学内容都是有些调整的，因为课程技术栈一直会更新，上新课之后就是5年后同学们拿到的视频和文档以及源码也是最新技术栈和生态的内容，这使得教学质量会更高</p>
</li>
<li class="">
<p>不再有所谓哪一期的限制，这样做就不需要一个所谓的固定的学习期限内学习完，可以一个月内学完，也可以等有时间断断续续学习，哪怕两年后依然能学习到最新的TS全栈开发知识。并且飞书一个群里就可以永久问答，不需要一下子在本期教室群一下子在总群循环切换来提问，所有常见问题一个群就可以统计</p>
</li>
</ul>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="课程内容">📝课程内容<a href="https://3rcd.com/blog/story#%E8%AF%BE%E7%A8%8B%E5%86%85%E5%AE%B9" class="hash-link" aria-label="📝课程内容的直接链接" title="📝课程内容的直接链接" translate="no">​</a></h3>
<blockquote>
<p>新课的目录表请查看<a href="https://3rcd.com/classroom" target="_blank" rel="noopener noreferrer" class="">官网</a></p>
</blockquote>
<p>因为讲课模式的改变，所以新课的内容和目录变得更加丰富与精细，因为不需要再在指定时间两小时内讲完一大部分的内容，而且切割成一小个一小个的小节，所以很多旧课程没有的东西，比如OAuth等等，都能加进去。</p>
<p>另外关于零基础的同学，我们目前有成熟的入门文档和助教预教学来带同学们入门</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="重点方向">✨重点方向<a href="https://3rcd.com/blog/story#%E9%87%8D%E7%82%B9%E6%96%B9%E5%90%91" class="hash-link" aria-label="✨重点方向的直接链接" title="✨重点方向的直接链接" translate="no">​</a></h3>
<p>虽然3R中的远程工作和远程外包我们会持续扩展，但是后面我们会把更多地精力放在为同学们提供远程自由职业及被动收入的创意上。</p>
<p>为什么这样做呢？</p>
<p>因为经过这段时间的摸索，发觉很多远程工作和外包开发的同学活得也比较累，虽说时间上的确是比较自由，但是花进去的碎片化时间可能比坐班还要更多，再加上无限的视频会议让人喘不过气。反倒是部分在搞个人作品或者平台的自由职业的同学不仅仅收入特别高，而且比较轻松，大多都是睡后至少也是被动收入。经过一段时间的调研和思考，我们发觉无论远程上班还是坐在公司上班又或是主动做外包，都很难有真正的自由，打工也并不是长久之计。所以后面后续规划将另辟蹊径，把需要3R教室的自由职业，创业以及被动收入等创意专门搞一个创意墙，然后把更多周边已经成功的朋友和同学的思路放上去，最后集思广益，去粗取精，使得大家可以更好地实现真正的被动收入</p>
<p>3R教室每个周末还会有个专门的茶话会去聊被动收入，睡后收入的方向与创意，鼓励更多的同学去实现</p>]]></content:encoded>
            <category>3R教室</category>
            <category>TS全栈开发</category>
            <category>远程工作</category>
            <category>海外外包</category>
        </item>
        <item>
            <title><![CDATA[3R教室历史事件及时间线]]></title>
            <link>https://3rcd.com/blog/timeline</link>
            <guid>https://3rcd.com/blog/timeline</guid>
            <pubDate>Tue, 24 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[我所经历的一切也许你即将踏入，你所走过的路也许我正在走，让我们共勉!]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-success admonition_M1T2 alert alert--success"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>success</div><div class="admonitionContent_ndgZ"><p>我所经历的一切也许你即将踏入，你所走过的路也许我正在走，让我们共勉!</p></div></div>
<!-- -->
<ul class="tw-timeline tw-timeline-vertical wrapper_L1nu"><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-06-22</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">平克小站正式上线</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">Rowfish正式开源</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-07-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-07-06</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">与愧怍小站交换链接</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">v.3rcd.com(Rowfish Pro)上线[已废弃]</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-07-09</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-07-10</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">知乎上来了一位订阅者，3R第一位付费用户</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-07-17</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">站长入职第一份国内远程工作</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">在boss直聘上承接第一个来自浙江杭州的项目: "诺思网站"</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-07-19</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-07-21</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">与第一份远程工作解约</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">签约第二份台湾远程工作</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-07-27</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-08-01</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">Rowfish被加入docusaurus官方的showcase</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">git.3rcd.com上线</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-08-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-08-05</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">因家庭事务主动离职</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-08-11</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室正式开始第一期(8名学员)，收费2999</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">飞书群及3R内部群上线</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-08-12</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-08-14</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">签约第三份加拿大远程工作</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">废弃v.3rcd.com</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-08-15</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-09-01</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室开始第二期(12名学员)，收费3699</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自台湾的"双北小宠物网站"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-09-03</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-09-13</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">承接来自美国的"Goflashdeal"项目</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">辞职后全职经营3R教室</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-09-25</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-10-01</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室第三期开始(25名学员)，收费不变</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">获得来自丹麦的一笔"98w"的投资</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-10-07</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-10-08</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">承接来自新西兰的"Lubolu"项目</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自加拿大的"Youni"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-10-18</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-10-22</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">玛卡巴卡成为助教</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">3R教室第四期开始(22名学员)，收费不变</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-11-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-11-09</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">承接来自丹麦的"旅游看客APP"项目</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自加拿大的"移民网站"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-12-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-12-05</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室第五期开始(24名学员)，收费不变</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自新加坡的"kro crm"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-12-09</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-12-13</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">欧欧成为项目总负责人</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自加拿大的N个"爬虫"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2022-12-15</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2022-12-19</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">承接来自浙江-绍兴的"同城直播交友小程序"项目</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">新课上线,持续招生,不再分期(13名学员),收费不变</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-01-03</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室纯营收突破50w(投资除外)</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">承接来自芬兰的"tradovel"项目</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-10</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-01-11</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">CC辰成为客户经理</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">突破100名学员</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-12</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-01-16</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">外包团队正式成立</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">翻译小组正式成立</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-18</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-01-21</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">新年快乐</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">社区开始开发</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-23</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">凌晨，上线此3R教室时间线</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-01-24</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-01-24</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室收费调整为4199</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">3R教室成员: 226人</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-05-07</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-07-01</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R英语教室成立: 讲师 @慧敏</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">3R教室会员费调整为4599，成员: 410人</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-10-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-10-05</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R工作室正式成立(原3R外包团队)</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">来自美国-波特兰的Sandy的爬虫项目开工</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-10-20</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-11-1</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R会员三哥的招财猫项目正式开工</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">来自英国客户的多租户商城项目开工</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-11-1</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-11-21</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R教室会员454人，盈利190w</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">专职助教: @cloneable，@愧怍</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-11-01</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-11-01</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">工作室开发者15人，主力开发: @欧欧，@愧怍</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">3R工作室进行中或已完结的项目(90%海外) 16个，总费用140w，利润60w</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-11-21</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start timeLabel_fJoo">2023-11-21</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end titleLabel_ZGfb">3R编码(教室与工作室)股东7人，分红售卖 190w</div></li><li class="!tw-my-0 block__Sf5"><div class="tw-timeline-start titleLabel_ZGfb">3R编码(教室与工作室)总收入 440w</div><div class="line_OHbV"><div class="lineContent_IiVi"></div><div class="lineDot_eKTA"><div class="dotContent_ez9p"></div></div></div><div class="tw-timeline-end timeLabel_fJoo">2023-11-21</div></li></ul>]]></content:encoded>
            <category>3R教室</category>
            <category>TS全栈开发</category>
            <category>远程工作</category>
            <category>海外外包</category>
            <category>自由职业</category>
            <category>被动收入</category>
        </item>
        <item>
            <title><![CDATA[深入理解Typescript装饰器]]></title>
            <link>https://3rcd.com/blog/ts-decorator</link>
            <guid>https://3rcd.com/blog/ts-decorator</guid>
            <pubDate>Thu, 23 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[在看本文前最好先看一下《阮一峰-es6中的装饰器》]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-tip admonition_M1T2 alert alert--success"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_ndgZ"><p>在看本文前最好先看一下<a href="http://es6.ruanyifeng.com/#docs/decorator" target="_blank" rel="noopener noreferrer" class="">《阮一峰-es6中的装饰器》</a></p></div></div>
<p>装饰器用于给类,方法,属性以及方法参数等增加一些附属功能而不影响其原有特性。其在Typescript应用中的主要作用类似于Java中的注解,在AOP(面向切面编程)使用场景下非常有用。</p>
<blockquote>
<p><strong>面向切面编程（AOP）</strong> 是一种编程范式，它允许我们分离<a href="https://zh.wikipedia.org/wiki/%E6%A8%AA%E5%88%87%E5%85%B3%E6%B3%A8%E7%82%B9" target="_blank" rel="noopener noreferrer" class="">横切关注点</a>，藉此达到增加模块化程度的目标。它可以在不修改代码自身的前提下，给已有代码增加额外的行为（通知）</p>
</blockquote>
<p><strong>装饰器一般用于处理一些与类以及类属性本身无关的逻辑</strong>,例如: 一个类方法的执行耗时统计或者记录日志,可以单独拿出来写成装饰器。</p>
<p>看一下官方的解释更加清晰明了</p>
<blockquote>
<p>装饰器是一种特殊类型的声明，它能够被附加到类声明，方法， 访问符，属性或参数上。 装饰器使用 <code>@expression</code>这种形式，<code>expression</code>求值后必须为一个函数，它会在运行时被调用，被装饰的声明信息做为参数传入。</p>
</blockquote>
<p>如果有使用过spring boot或者php的symfony框架的话,就基本知道装饰器的作用分别类似于以上两者注解和annotation，而node中装饰器用的比较好的框架是nest.js。不过不了解也没关系,接下来我就按我的理解讲解一下装饰器的使用。</p>
<p>不过目前装饰器还不属于标准，还在建议征集的第二阶段，但这并不妨碍我们在ts中的使用。只要在 <code>tsconfig.json</code>中开启 <code>experimentalDecorators</code>编译器选项就可以愉快地使用啦^^</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-json codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-json codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"compilerOptions"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"target"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ES5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"experimentalDecorators"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本概念">基本概念<a href="https://3rcd.com/blog/ts-decorator#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5" class="hash-link" aria-label="基本概念的直接链接" title="基本概念的直接链接" translate="no">​</a></h2>
<p>可能有些时候，我们会对传入参数的类型判断、对返回值的排序、过滤，对函数添加节流、防抖或其他的功能性代码，基于多个类的继承，各种各样的与函数逻辑本身无关的、重复性的代码。</p>
<p>比如,我们要在用户登录的时候记录一下登录时间</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">logger</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">now</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">lasted logged in </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">now</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'login success'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">logger</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">valueOf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>以上代码把记录日志的代码强行写入登录的逻辑处理,这样代码量越高则代码越冗余。我们需要把日志逻辑单独拿出来，使login方法更专注于处理登录的逻辑,接下去我们用高阶函数模拟一下装饰器的原理,以便于后面更好的理解装饰器。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * 使用高阶函数</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * 柯里化解构登录与日志记录</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">DecoratorFunc</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 模拟的装饰器工厂函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">createDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">decorator</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> DecoratorFunc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Model</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 获取即将使用装饰器的类原型</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> target </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Model</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 获取这个原型上某个方法的描述</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> descriptor </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getOwnPropertyDescriptor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 更改描述,生成新的方法</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">decorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> logger</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">DecoratorFunc</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 将修改后的函数重新定义到原型链上</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">defineProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">...</span><span class="token plain">descriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 调用之前的函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> now </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">valueOf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">lasted logged in </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">now</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'login success'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name builtin">Promise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例1:高阶函数柯里化(装饰器内部原理)-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------实现登录和日志记录解耦-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> loggerDecorator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">loggerDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">User</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'login'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例1:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// login success</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 停顿100ms</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// lasted logged in 1571771681793</span><br></span></code></pre></div></div></div></div>
<p>了解了以上概念,接下去让我们学习真正的装饰器。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="装饰器类型"><strong>装饰器类型</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%A3%85%E9%A5%B0%E5%99%A8%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="装饰器类型的直接链接" title="装饰器类型的直接链接" translate="no">​</a></h2>
<p>TS中的装饰器有几种类型，如下：</p>
<ul>
<li class="">
<p>参数装饰器</p>
</li>
<li class="">
<p>方法装饰器</p>
</li>
<li class="">
<p>访问符装饰器</p>
</li>
<li class="">
<p>属性装饰器</p>
</li>
<li class="">
<p>类装饰器</p>
</li>
</ul>
<p>以上每中装饰器分别可以作用于类原型(<em>prototype</em>属性)和类本身</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="类装饰器"><strong>类装饰器</strong><a href="https://3rcd.com/blog/ts-decorator#%E7%B1%BB%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="类装饰器的直接链接" title="类装饰器的直接链接" translate="no">​</a></h3>
<p><a href="https://www.typescriptlang.org/docs/handbook/decorators.html" target="_blank" rel="noopener noreferrer" class="">TS官方文档</a>中举了一个类装饰器的例子,也可以看一下。类装饰器其实就是把我们本身的类传入装饰器注解中,并对这个类或类的原型进行一些处理，仅此而已。例如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> HelloDerorator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constructor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">extends</span><span class="token plain"> constructor </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        newProperty </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'new property'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        hello </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'override'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">sayHello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">hello</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">HelloDerorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Hello</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 此处用于防止eslint提示sayHello方法不存在</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    hello</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">hello </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'test'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例2:简单的类装饰器-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------动态添加一个sayHello方法以及覆盖hello的值-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> hello </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">hello</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">sayHello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例2:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台打印 override</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="装饰器工厂"><strong>装饰器工厂</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%A3%85%E9%A5%B0%E5%99%A8%E5%B7%A5%E5%8E%82" class="hash-link" aria-label="装饰器工厂的直接链接" title="装饰器工厂的直接链接" translate="no">​</a></h4>
<p>上面的方法我们为<code>UserService</code>添加了一个<code>HelloDerorator</code>装饰器，这个装饰器的属性将覆盖<code>UserService</code>的默认属性。为了方便给装饰器添加其它参数，我们把<code>HelloDerorator</code>改造成为一个装饰器工厂,如下：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">SetNameDerorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">firstname</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> lastname</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">firstname</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">lastname</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">extends</span><span class="token plain"> target </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            _name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">getMyName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">SetNameDerorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'jesse'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'pincman'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp3</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例3:装饰器工厂-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------通过继承方式 重载getName方法-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例3:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台打印 jesse.pincman</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="其它用法"><strong>其它用法</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%85%B6%E5%AE%83%E7%94%A8%E6%B3%95" class="hash-link" aria-label="其它用法的直接链接" title="其它用法的直接链接" translate="no">​</a></h4>
<p>我们还可以对类原型链<code>property</code>上的属性/方法和类本身的静态属性/方法进行赋值或重载操作，还可以重载构造函数，如下：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">UserProfile</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Record</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    phone</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    address</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">ProfileDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">profile</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserProfile</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> Original </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> userinfo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">keys</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">profile</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        userinfo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">userinfo</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">profile</span><span class="token template-string interpolation punctuation" style="color:#393A34">[</span><span class="token template-string interpolation">key</span><span class="token template-string interpolation punctuation" style="color:#393A34">]</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation function" style="color:#d73a49">toString</span><span class="token template-string interpolation punctuation" style="color:#393A34">(</span><span class="token template-string interpolation punctuation" style="color:#393A34">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 添加一个原型属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Original</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">userinfo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> userinfo</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 使用函数创建一个新的类(类构造器),返回值为传入类的对象,这样就重载了构造函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'contruct has been changed'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Original</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 赋值原型链</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constructor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Original</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 添加一个静态属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// constructor.myinfo = `myinfo ${userinfo}`;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> constructor </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> Original</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 因为静态属性是无法通过[key: string]: any;获取类型提示的,所以这里添加一个接口用于动态各类添加静态属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">interface</span><span class="token plain"> </span><span class="token class-name">StaticUser</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserService</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    myinfo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">ProfileDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> phone</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">133</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> address</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'zhejiang'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">ProfileService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp4</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例4:修类的构造函数,原型属性,静态属性等-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------设置原型属性值,重载构造防反,添加静态属性-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// console.log((ProfileService as unknown as StaticUser).myinfo);</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> profile </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">ProfileService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">profile </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">userinfo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例4:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 打印静态属性则控制台输出 myinfo .133.zhejiang</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出 contruct has been changed</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出 .133.zhejiang</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="属性装饰器"><strong>属性装饰器</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%B1%9E%E6%80%A7%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="属性装饰器的直接链接" title="属性装饰器的直接链接" translate="no">​</a></h2>
<p>属性装饰器一般不单独使用，主要用于配合类或方法装饰器进行组合装饰</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="参数"><strong>参数</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%8F%82%E6%95%B0" class="hash-link" aria-label="参数的直接链接" title="参数的直接链接" translate="no">​</a></h3>
<p>属性装饰器函数有两个参数：</p>
<p><strong>target</strong></p>
<p>对于普通属性，target就是当前对象的原型，也就是说，假设 Employee 是对象，那么 target 就是 <code>Employee.prototype</code></p>
<p>对于静态属性，target就是当前对象的类</p>
<p><strong>propertyKey</strong></p>
<p>属性的名称</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用示例"><strong>使用示例</strong><a href="https://3rcd.com/blog/ts-decorator#%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="使用示例的直接链接" title="使用示例的直接链接" translate="no">​</a></h3>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> userRoles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 通过属性装饰器把角色赋值给userRoles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">RoleDerorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">roles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    roles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> userRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 根据userRoles生成Roles对象并赋值给类原型的roles属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> SetRoleDerorator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token constant" style="color:#36acaa">T</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constructor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> roles </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'super-admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> desc</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'超级管理员'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> desc</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'管理员'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> desc</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'普通用户'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">extends</span><span class="token plain"> constructor </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">super</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">roles </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> roles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> userRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">role</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">SetRoleDerorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserEntity</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">RoleDerorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    roles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例5:属性装饰器-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------使用装饰器根据权限过滤用户列表-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserEntity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">roles</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例5:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出 [ { name: 'admin', desc: '管理员' }, { name: 'user', desc: '普通用户' } ]</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="方法装饰器"><strong>方法装饰器</strong><a href="https://3rcd.com/blog/ts-decorator#%E6%96%B9%E6%B3%95%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="方法装饰器的直接链接" title="方法装饰器的直接链接" translate="no">​</a></h2>
<p>在一开始我们介绍了装饰器的原理,其实这就是方法装饰器的原始实现。与属性装饰器不同的是,方法装饰器接受三个参数</p>
<blockquote>
<p>方法装饰器重载的时候需要注意的一点是定义value务必使用function，而不是箭头函数，因为我们在调用原始的旧方法使用会使用到this，如：method.apply(this, args)，这里的this指向需要function来定义，具体原因可参考我的另一篇文章<a href="https://test.3rcd.com/" target="_blank" rel="noopener noreferrer" class="">apply,bind,call使用</a></p>
</blockquote>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="参数-1"><strong>参数</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%8F%82%E6%95%B0-1" class="hash-link" aria-label="参数-1的直接链接" title="参数-1的直接链接" translate="no">​</a></h3>
<p><strong>target</strong></p>
<p>对于静态成员来说是类的构造函数，对于实例成员是类的原型对象。</p>
<p><strong>key</strong></p>
<p>方法名称</p>
<p><strong>descriptor: PropertyDescriptor</strong></p>
<p>方法的属性描述符(最重要的参数)</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="属性描述符"><strong>属性描述符</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%B1%9E%E6%80%A7%E6%8F%8F%E8%BF%B0%E7%AC%A6" class="hash-link" aria-label="属性描述符的直接链接" title="属性描述符的直接链接" translate="no">​</a></h3>
<p>属性描述包含以下几个属性</p>
<ul>
<li class="">
<p>configurable?: boolean; // 能否使用delete、能否修改方法特性或修改访问器属性</p>
</li>
<li class="">
<p>enumerable?: boolean;  是否在遍历对象的时候存在</p>
</li>
<li class="">
<p>value?: any;  用于定义新的方法代替旧方法</p>
</li>
<li class="">
<p>writable?: boolean; 是否可写</p>
</li>
<li class="">
<p>get?(): any; // 访问器</p>
</li>
<li class="">
<p>set?(v: any): void; // 访问器</p>
</li>
</ul>
<p>接下来我们使用方法装饰器修改一开始的装饰器原理中的登录日志记录器</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">loggerDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">logMethod</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyDescriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> method </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> propertyDescriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 重载方法</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyDescriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 调用之前的函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> now </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">valueOf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">lasted logged in </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">now</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> propertyDescriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">loggerDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'login success'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name builtin">Promise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp6</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例6:方法装饰器-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------使用装饰器重写示例1-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例6:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出结果与前面的示例1相同</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="参数装饰器"><strong>参数装饰器</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%8F%82%E6%95%B0%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="参数装饰器的直接链接" title="参数装饰器的直接链接" translate="no">​</a></h2>
<p>一个类中每个方法的参数也可以有自己的装饰器。</p>
<blockquote>
<p>与属性装饰器类似，参数装饰器一般不单独使用，而是配合类或方法装饰器组合使用</p>
</blockquote>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="参数-2"><strong>参数</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%8F%82%E6%95%B0-2" class="hash-link" aria-label="参数-2的直接链接" title="参数-2的直接链接" translate="no">​</a></h3>
<ol>
<li class="">
<p>target: 对于静态成员来说是类的构造函数，对于实例成员是类的原型对象。</p>
</li>
<li class="">
<p>key:方法名称</p>
</li>
<li class="">
<p>index: 参数数组中的位置</p>
</li>
</ol>
<p>比如我们需要格式化一个方法的参数,那么可以创建一个转么用于格式化的装饰器</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 参数格式化配置</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> parseConf</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">parse</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function-variable function" style="color:#d73a49">parseTo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> index</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        parseConf</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> parseTo</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 在函数调用前执行格式化操作</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> parseDecorator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'开始格式化数据'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">...</span><span class="token plain">descriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 获取格式化后的参数列表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> newArgs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                parseConf</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> parseConf</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">v</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> v</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'格式化完毕'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> newArgs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">interface</span><span class="token plain"> </span><span class="token class-name">UserType</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> users</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserType</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'pincman'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parseDecorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Number</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userObj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> userObj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp78</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例7:参数装饰器-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------格式化参数-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> userService </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    userService</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userService</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例7:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出: [ { id: 2, username: 'pincman' } ]</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="访问器装饰器"><strong>访问器装饰器</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%AE%BF%E9%97%AE%E5%99%A8%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="访问器装饰器的直接链接" title="访问器装饰器的直接链接" translate="no">​</a></h3>
<p>访问器其实只是那些添加了<code>get</code>,<code>set</code>前缀的方法，用于使用调用属性的方式获取和设置一些属性的方法，类似于PHP中的魔术方法<code>__get</code>,<code>__set</code>。其装饰器使用方法与普通方法并无差异，只是在获取值的时候是调用描述符的<code>get</code>和<code>set</code>来替代<code>value</code>而已。</p>
<p>例如，我们添加一个<em>nickname</em>字段，给设置<em>nickname</em>添加一个自定义前缀，并禁止在遍历<em>user</em>对象时出现<em>nickname</em>的值，添加一个<em>fullname</em>字段，在设置<em>nickname</em>时添加一个字符串后缀生成。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">HiddenDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">enumerable </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">PrefixDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">prefix</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">...</span><span class="token plain">descriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">prefix</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">value</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserEntity</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> _nickname</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// @ts-ignore</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> fullname</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">HiddenDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">PrefixDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'jesse_'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nickname</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_nickname</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">set</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nickname</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_nickname </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">fullname </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">value</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">_fullname</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp78</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例8:get/set装饰器-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------禁止nickname出现在遍历中,为nickname添加前缀-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserEntity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">nickname </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'pincman'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">nickname</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例8:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 第一个console.log控制台输出,可以看到遍历对象后并没有nickname字段的值</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// UserService {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  users: [ { id: 1, username: 'admin' }, { id: 2, username: 'pincman' } ],</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  roles: [],</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  hello: 'test',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  password: '123456',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  _nickname: 'gkr__lichnow',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//  fullname: 'gkr__lichnow_fullname'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 第二个console.log控制台输出</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// gkr__lichnow</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="装饰器写法"><strong>装饰器写法</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%A3%85%E9%A5%B0%E5%99%A8%E5%86%99%E6%B3%95" class="hash-link" aria-label="装饰器写法的直接链接" title="装饰器写法的直接链接" translate="no">​</a></h2>
<p>通过装饰器重载方法有许多写法，可以根据自己的喜好来，以下举例几种</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="继承法"><strong>继承法</strong><a href="https://3rcd.com/blog/ts-decorator#%E7%BB%A7%E6%89%BF%E6%B3%95" class="hash-link" aria-label="继承法的直接链接" title="继承法的直接链接" translate="no">​</a></h3>
<p>一般用于类装饰器中添加属性或方法，例如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">extends</span><span class="token plain"> target </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token function" style="color:#d73a49">getMyName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="原型法"><strong>原型法</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%8E%9F%E5%9E%8B%E6%B3%95" class="hash-link" aria-label="原型法的直接链接" title="原型法的直接链接" translate="no">​</a></h3>
<p>一般用于类装饰器上重载构造函数以及添加属性或方法，例如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">ProfileDerorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">profile</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserProfile</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> original </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'contruct has been changed'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">original</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 赋值原型链</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constructor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> original</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">prototype</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 添加一个静态属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constructor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">myinfo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">myinfo </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">userinfo</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> constructor </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> original</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="赋值法"><strong>赋值法</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%B5%8B%E5%80%BC%E6%B3%95" class="hash-link" aria-label="赋值法的直接链接" title="赋值法的直接链接" translate="no">​</a></h3>
<p>一般用于方法装饰器上修改某个描述符，例如</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">loggerDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">logMethod</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Object</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyDescriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> method </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> propertyDescriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 重载方法</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyDescriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">...</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> propertyDescriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="展开法"><strong>展开法</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%B1%95%E5%BC%80%E6%B3%95" class="hash-link" aria-label="展开法的直接链接" title="展开法的直接链接" translate="no">​</a></h3>
<p>与赋值法类似，只不过使用ES6+的展开语法，更容易理解和使用，例如</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> parseFunc </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Object</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">...</span><span class="token plain">descriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// 获取格式化后的参数列表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> newArgs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> parseConf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">toParse</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">toParse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> newArgs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="元信息反射-api"><strong>元信息反射</strong> <strong>API</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%85%83%E4%BF%A1%E6%81%AF%E5%8F%8D%E5%B0%84-api" class="hash-link" aria-label="元信息反射-api的直接链接" title="元信息反射-api的直接链接" translate="no">​</a></h2>
<p>元信息反射 API （例如 <code>Reflect</code>）能够用来以标准方式组织元信息。而装饰器中的<em>元信息反射</em>使用非常简单，外观上仅仅可以看做在类的某个方法上附加一些随时可以获取的信息而已。</p>
<p>使用之前我们必须先安装<code>reflect-metadata</code>这个库</p>
<p>npm i reflect-metadata --save</p>
<p>并且在<code>tsconfig.json</code>中启用原信息配置</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">"compilerOptions"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"target"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ES5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"experimentalDecorators"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"emitDecoratorMetadata"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本使用"><strong>基本使用</strong><a href="https://3rcd.com/blog/ts-decorator#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="基本使用的直接链接" title="基本使用的直接链接" translate="no">​</a></h3>
<p>我们看一下TS官方的示例是如何通过反射API获取属性设计阶段的类型信息的。</p>
<p>需要注意的是目前预定义的元信息只有三种</p>
<ul>
<li class="">
<p>类型元信息:  <code>design:type</code>。</p>
</li>
<li class="">
<p>参数类型元信息:  <code>design:paramtypes</code>。</p>
</li>
<li class="">
<p>返回类型元信息:  <code>design:returntype</code>。</p>
</li>
</ul>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'reflect-metadata'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> parse</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parseDecorator</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> UserType </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./exp7-8'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Point</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    y</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Line</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> _p0</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Point</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> _p1</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Point</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">validate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 这句可以省略,因为design:type是预定义属性</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// @Reflect.metadata('design:type', Point)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">set</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">p0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Point</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_p0 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">p0</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_p0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">validate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// @Reflect.metadata("design:type", Point)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">set</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">p1</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Point</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_p1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">p1</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">_p1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token generic-function function" style="color:#d73a49">validate</span><span class="token generic-function generic class-name operator" style="color:#393A34">&lt;</span><span class="token generic-function generic class-name constant" style="color:#36acaa">T</span><span class="token generic-function generic class-name operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyKey</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> TypedPropertyDescriptor</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> set </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">set</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> type </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'design:type'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> propertyKey</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value </span><span class="token keyword" style="color:#00009f">instanceof</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">type</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">TypeError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Invalid type.'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp910</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例9:基本元元素类型反射-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------为访问器的set方法添加类型验证-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> line </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Line</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> p0 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Point</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    p0</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    p0</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    line</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">p1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> p0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">line</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-----------------------示例9:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台输出: Line { _p1: Point { x: 1, y: 2 } }</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义元信息"><strong>自定义元信息</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%85%83%E4%BF%A1%E6%81%AF" class="hash-link" aria-label="自定义元信息的直接链接" title="自定义元信息的直接链接" translate="no">​</a></h3>
<p>除了使用类似<code>design:type</code>这种预定义的原信息外，我们也可以自定义信息，因为一般我们都是用<code>reflect-metadata</code>来自定义原信息的。比如我们可以在删除用户的方法上添加一个角色判断，只有拥有我们设定角色的用户才能删除用户，比如管理员角色，具体可参考以下代码：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 角色守卫</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">RoleGuardDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">roles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'开始验证角色'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">roleGuard</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyKey</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// 根据传入的参数定义守卫所需的角色</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">defineMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'roles'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> roles</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> propertyKey</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> method </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 获取当前用户的角色</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> currentRoles </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 获取我们定义的操作此方法所需的角色</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> needRoles </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'roles'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> propertyKey</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 判断当前用户是否拥有所需的角色,没有则抛出异常</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> role </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> needRoles</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">currentRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                        </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">you have not permission to run </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">propertyKey</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'验证角色完毕'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">protected</span><span class="token plain"> users</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserType</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'pincman'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 设定当前用户的角色</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">RoleGuardDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 在装饰器中使用Reflect.defineMetadata()放定义roles只是为了方便封装</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 当然,我们也可以在方法上直接定义roles,如下</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Reflect.metadata('roles',['admin'])</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parseDecorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Number</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserService </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userObj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> userObj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp910</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例10:自定义元元素反射-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------添加角色守卫来判断当前用户是否有删除权限-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例10:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 控制台将输出异常</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Error: you have not permission to run delete</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="组合与顺序"><strong>组合与顺序</strong><a href="https://3rcd.com/blog/ts-decorator#%E7%BB%84%E5%90%88%E4%B8%8E%E9%A1%BA%E5%BA%8F" class="hash-link" aria-label="组合与顺序的直接链接" title="组合与顺序的直接链接" translate="no">​</a></h2>
<p>每一个属性,参数或方法都可以使用多组装饰器。每个类型的装饰器的调用顺序也是不同的。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="组合使用"><strong>组合使用</strong><a href="https://3rcd.com/blog/ts-decorator#%E7%BB%84%E5%90%88%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="组合使用的直接链接" title="组合使用的直接链接" translate="no">​</a></h3>
<p>我们可以对任意一个被装饰者调用多组装饰器，多组装饰器一般书写在多行上(当然你也可以写在一行上，多行书写只不过是个约定俗成的惯例)，比如</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">RoleGuardDecorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parseDecorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Number</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserService </span><br></span></code></pre></div></div></div></div>
<p>当多个装饰器应用于一个声明上，它们求值方式与<a href="http://en.wikipedia.org/wiki/Function_composition" target="_blank" rel="noopener noreferrer" class="">高阶函数</a>相似。在这个模型下，当复合*<code>RoleGuardDecorator</code><em>和</em><code>parseDecorator</code><em>时，复合的结果等同于</em><code>RoleGuardDecorator</code><em><code>(</code></em><code>parseDecorator</code><em><code>(</code></em><code>delete</code>*<code>))</code>。</p>
<p>同时，我们可以参考react中的<a href="https://zh-hans.reactjs.org/docs/higher-order-components.html" target="_blank" rel="noopener noreferrer" class="">高阶</a>，原理相似</p>
<p>它们的调用步骤类似剥洋葱法，即：</p>
<ol>
<li class="">
<p>由上至下依次对装饰器表达式求值。</p>
</li>
<li class="">
<p>求值的结果会被当作函数，由下至上依次调用。</p>
</li>
</ol>
<p>比如</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">parseDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'开始格式化数据'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Object</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">...</span><span class="token plain">descriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> newArgs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> parseConf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">toParse</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">toParse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'格式化完毕'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> newArgs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">RoleGuardDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">roles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">roleGuard</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyKey</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> PropertyDescriptor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'开始验证角色'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'验证角色完毕'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">RoleGuardDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 把parseDecorator改成parseDecorator()</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">parseDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">getRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 提供验证角色为admin</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="调用顺序"><strong>调用顺序</strong><a href="https://3rcd.com/blog/ts-decorator#%E8%B0%83%E7%94%A8%E9%A1%BA%E5%BA%8F" class="hash-link" aria-label="调用顺序的直接链接" title="调用顺序的直接链接" translate="no">​</a></h3>
<blockquote>
<p>特别需要注意的是<code>getMetadata</code>与<code>getOwneMetadata</code>的<a href="https://stackoverflow.com/questions/48509376/whats-the-difference-between-reflect-getmetadata-and-reflect-getownmetadata" target="_blank" rel="noopener noreferrer" class="">区别</a></p>
</blockquote>
<p>每种类型的装饰器的调用顺序是不同的，具体顺序如下：</p>
<ol>
<li class="">
<p><em>参数装饰器</em>，然后依次是<em>方法装饰器</em>，<em>访问符装饰器</em>，或<em>属性装饰器</em>应用到每个实例成员(即类原型的成员)。</p>
</li>
<li class="">
<p><em>参数装饰器</em>，然后依次是<em>方法装饰器</em>，<em>访问符装饰器</em>，或<em>属性装饰器</em>应用到每个静态成员。</p>
</li>
<li class="">
<p><em>参数装饰器</em>应用到构造函数(即类原型)。</p>
</li>
<li class="">
<p><em>类装饰器</em>应用到类。</p>
</li>
</ol>
<p>例如：我们使用元信息结合方法和参数装饰器来验证参数的<em>required</em>，其调用顺序为<em>参数装饰器</em>-&gt;<em>方法装饰器</em></p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-TypeScript language-typescript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-typescript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * 装饰器调用顺序</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> UserType </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./exp7-8'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> UserService </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> ParentUserService </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./exp9-10'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> requiredMetadataKey </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Symbol</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'required'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">RequiredDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyKey</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token builtin">symbol</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    parameterIndex</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> existingRequiredParameters</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getOwnMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requiredMetadataKey</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> propertyKey</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    existingRequiredParameters</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">parameterIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">defineMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        requiredMetadataKey</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        existingRequiredParameters</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        propertyKey</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">ValidateDecorator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> TypedPropertyDescriptor</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> method </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    descriptor</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> requiredParameters</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getOwnMetadata</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            requiredMetadataKey</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            target</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            propertyName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requiredParameters</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> parameterIndex </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> requiredParameters</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    parameterIndex </span><span class="token operator" style="color:#393A34">&gt;=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">length </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    args</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">parameterIndex</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">undefined</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Missing required argument.'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">method</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">apply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">ParentUserService</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">ValidateDecorator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">createUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">RequiredDecorator</span><span class="token plain"> username</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ids</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userEntity</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> userEntity</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> newUser</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UserType </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 如果不提供ID参数,则新用户的ID为所有用户的最大ID + 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> id </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">...</span><span class="token plain">ids</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// 如果不提供username参数,则生成随机字符串作为用户名</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            username</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> username </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">random</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">36</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">substring</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">users</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">newUser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> newUser</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">exp11</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例11:装饰器组合-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------为username参数提供必填验证-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">createUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getUsers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'-----------------------示例11:执行完毕-----------------------'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>]]></content:encoded>
            <category>typescript</category>
            <category>mariadb</category>
            <category>linux</category>
        </item>
        <item>
            <title><![CDATA[class-validator和class-transformer的中文文档]]></title>
            <link>https://3rcd.com/blog/class-validator-and-class-transformer-cn</link>
            <guid>https://3rcd.com/blog/class-validator-and-class-transformer-cn</guid>
            <pubDate>Wed, 22 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[随着时间的推移，可能部分内容无法与官方最新版本同步，请自行对比查看，我有空会更新]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-caution admonition_M1T2 alert alert--warning"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>警告</div><div class="admonitionContent_ndgZ"><p>随着时间的推移，可能部分内容无法与官方最新版本同步，请自行对比查看，我有空会更新</p></div></div>
<p>用于Typescript或ES6+的类验证，基于<a href="https://github.com/chriso/validator.js" target="_blank" rel="noopener noreferrer" class="">validator.js</a></p>
<p><a href="https://github.com/typestack/class-validator#manual-validation" target="_blank" rel="noopener noreferrer" class="">手动验证方法列表</a>和<a href="https://github.com/typestack/class-validator#validation-decorators" target="_blank" rel="noopener noreferrer" class="">验证装饰器列表</a></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="class-validator中文文档">class-validator中文文档<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#class-validator%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3" class="hash-link" aria-label="class-validator中文文档的直接链接" title="class-validator中文文档的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="安装">安装<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h3>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">npm install class-validator --save</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本使用">基本使用<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="基本使用的直接链接" title="基本使用的直接链接" translate="no">​</a></h4>
<p>创建一个<code>Post</code>作为演示,在每个属性上添加不同的验证<a href="https://test.3rcd.com/notes/decorator.html" target="_blank" rel="noopener noreferrer" class="">装饰器</a>尝试</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> validateOrReject</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Contains</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsInt</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Length</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsEmail</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsFQDN</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsDate</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Min</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Max</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Length</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsInt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">rating</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsFQDN</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">site</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsDate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">createDate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> post </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">title</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// should not pass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">text</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"this is a great post about hell world"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// should not pass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">rating</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">11</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// should not pass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">email</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"google.com"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// should not pass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">site</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"googlecom"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// should not pass</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 如果验证失败不会停止运行程序</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"validation failed. errors: "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"validation succeed"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 验证失败就停止运行程序</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validateOrReject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Promise rejected (validation failed). Errors: "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 或者</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">validateOrRejectExample</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">input</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">validateOrReject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">input</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">errors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Caught promise rejection (validation failed). Errors: "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="选项">选项<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%80%89%E9%A1%B9" class="hash-link" aria-label="选项的直接链接" title="选项的直接链接" translate="no">​</a></h4>
<p><code>validate</code>函数的第二个参数是一个选项对象，尽量设置<code>forbidNonWhitelisted</code>为<code>true</code>以避免unkown对象的输入验证</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">interface</span><span class="token plain"> </span><span class="token class-name">ValidatorOptions</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    skipMissingProperties</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    whitelist</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    forbidNonWhitelisted</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    groups</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    dismissDefaultMessages</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    validationError</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        target</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        value</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    forbidUnknownValues</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证错误">验证错误<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81%E9%94%99%E8%AF%AF" class="hash-link" aria-label="验证错误的直接链接" title="验证错误的直接链接" translate="no">​</a></h4>
<p>验证失败返回的错误数组是<code>ValidationError</code>类的对象的数组，格式如下</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Object</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Object that was validated.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">property</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Object's property that haven't pass validation.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> any</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Value that haven't pass a validation.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    constraints</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Constraints that failed validation with error messages.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    children</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">ValidationError</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Contains all nested validation errors of the property</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>返回的格式如下</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* post object */</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">property</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"title"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">constraints</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">length</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"$property must be longer than or equal to 10 characters"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* post object */</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">property</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"this is a great post about hell world"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">constraints</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">contains</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"text must contain a hello string"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// and other errors</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre></div></div></div></div>
<p>在http响应中我们一般不想在错误中暴露<code>target</code>，那么就可以如下方式禁用它</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">validator</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">validationError</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证消息">验证消息<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81%E6%B6%88%E6%81%AF" class="hash-link" aria-label="验证消息的直接链接" title="验证消息的直接链接" translate="no">​</a></h4>
<p>我们可以自定义在<code>ValidationError</code>对象中返回的错误消息</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Title is too short"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Title is too long"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>消息可以接受几个参数作为变量，用字符串混合的方式放入，比如<code>"$constraint1 characters"</code></p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// here, $constraint1 will be replaced with "10", and $value with actual supplied value</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Title is too short. Minimal length is $constraint1 characters, but actual is $value"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// here, $constraint1 will be replaced with "50", and $value with actual supplied value</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Title is too long. Maximal length is $constraint1 characters, but actual is $value"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>能接受的变量如下</p>
<ul>
<li class=""><code>value</code> - 被验证的值</li>
<li class=""><code>constraints</code> - 由指定验证类型定义的约束数组</li>
<li class=""><code>targetName</code> - 验证对象的类的名称</li>
<li class=""><code>object</code> - 被验证的对象</li>
<li class=""><code>property</code> - 被验证的属性名</li>
</ul>
<p>当然<code>message</code>还可以接受一个函数的返回值，这个函数的参数为<code>ValidationArguments</code>类的对象，而<code>ValidationArguments</code>类的属性就是上面的变量列表</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationArguments</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function-variable function" style="color:#d73a49">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">args</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Too short, minimum length is 1 character"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Too short, minimum length is "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constraints</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" characters"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="特殊类型">特殊类型<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E7%89%B9%E6%AE%8A%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="特殊类型的直接链接" title="特殊类型的直接链接" translate="no">​</a></h3>
<p><code>class-validator</code>对一些经常使用的特殊类型有专门的处理方法</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="集合类型">集合类型<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%9B%86%E5%90%88%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="集合类型的直接链接" title="集合类型的直接链接" translate="no">​</a></h4>
<p>验证数组,<code>Sets</code>,<code>Map</code>等集合类型需要开启<code>each</code>选项</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证数组">验证数组<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81%E6%95%B0%E7%BB%84" class="hash-link" aria-label="验证数组的直接链接" title="验证数组的直接链接" translate="no">​</a></h4>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">each</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">tags</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证sets">验证Sets<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81sets" class="hash-link" aria-label="验证Sets的直接链接" title="验证Sets的直接链接" translate="no">​</a></h4>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">each</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">tags</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Set</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">string</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证map">验证Map<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81map" class="hash-link" aria-label="验证Map的直接链接" title="验证Map的直接链接" translate="no">​</a></h4>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">MinLength</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">MaxLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">each</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">tags</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Map</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> string</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="嵌套对象">嵌套对象<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1" class="hash-link" aria-label="嵌套对象的直接链接" title="嵌套对象的直接链接" translate="no">​</a></h4>
<p>一个验证的类中的某些属性可能是类一个的对象，比如<code>Post</code>类的<code>user</code>属性为<code>User</code>类，则可以使用<code>@ValidateNested()</code>方式来同时验证<code>Post</code>和嵌入的<code>User</code>类</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidateNested</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">ValidateNested</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">user</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="promise对象">Promise对象<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#promise%E5%AF%B9%E8%B1%A1" class="hash-link" aria-label="Promise对象的直接链接" title="Promise对象的直接链接" translate="no">​</a></h4>
<p>如果待验证的属性是一个<code>Promise</code>对象，比如通过<code>await</code>关键字返回的值，则可以使用<code>@ValidatePromise()</code></p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidatePromise</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Min</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">ValidatePromise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">userId</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">number</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p><code>@ValidatePromise()</code>也可以和<code>@ValidateNested()</code>一起使用</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidateNested</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatePromise</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">ValidateNested</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">ValidatePromise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">user</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">User</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="高级主题">高级主题<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AB%98%E7%BA%A7%E4%B8%BB%E9%A2%98" class="hash-link" aria-label="高级主题的直接链接" title="高级主题的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="子类验证">子类验证<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%AD%90%E7%B1%BB%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="子类验证的直接链接" title="子类验证的直接链接" translate="no">​</a></h4>
<p>如果定义一个从另一个继承的子类时，子类将自动继承父级的装饰器。如果在后代类中重新定义了属性，则装饰器将从该类和基类中继承</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">BaseContent</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">BaseContent</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MaxLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">welcome</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">email</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"invalid email"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// inherited property</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">password</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"too short"</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// password wil be validated not only against IsString, but against MinLength as well</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"not valid"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">welcome</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"helo"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// it will return errors for email, title and text properties</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="条件验证">条件验证<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%9D%A1%E4%BB%B6%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="条件验证的直接链接" title="条件验证的直接链接" translate="no">​</a></h4>
<p>当某个属性需要满足一定条件验证时可以使用(<code>@ValidateIf</code>)装饰器</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidateIf</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsNotEmpty</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">otherProperty</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">ValidateIf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">o</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">otherProperty</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"value"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsNotEmpty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">example</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="白名单">白名单<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E7%99%BD%E5%90%8D%E5%8D%95" class="hash-link" aria-label="白名单的直接链接" title="白名单的直接链接" translate="no">​</a></h4>
<p>一个被验证的类的对象可以定义在类中不存在的属性，在验证时不会产生错误。为了使只有添加了<strong>验证装饰器</strong>的属性才能被定义，你需要把<code>whitelist</code>设置为<code>true</code>，那么如果对象中定义一个类中不存在的属性就无法通过验证了。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">whitelist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>开启白名单之后所有没有加上<strong>验证装饰器</strong>的属性被定义后都将无法通过验证，如果你想一些属性可以被定义但是又不想被验证，如果<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%9D%A1%E4%BB%B6%E9%AA%8C%E8%AF%81" class="">条件验证</a>中的<code>otherProperty</code>属性，那么你需要在该属性上面添加一个<code>@Allow</code>装饰器</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * title可以被定义</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * nonWhitelistedProperty不能被定义，否则验证失败</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Allow</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Min</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Allow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">views</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">nonWhitelistedProperty</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> post </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">title</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Hello world!'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">views</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">420</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">nonWhitelistedProperty</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">69</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 额外属性不能被添加，否则验证失败</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post </span><span class="token keyword module" style="color:#00009f">as</span><span class="token plain"> any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">anotherNonWhitelistedProperty</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"something"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// post.nonWhitelistedProperty is not defined</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// (post as any).anotherNonWhitelistedProperty is not defined</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>如果你想要所有没有添加<strong>验证装饰器</strong>的属性都无法定义，则可以设置<code>forbidNonWhitelisted</code>为<code>true</code></p>
<blockquote>
<p>这个一般不要设置，否则属性添加@Allow会都没用了</p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">whitelist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">forbidNonWhitelisted</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="添加上下文">添加上下文<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%B7%BB%E5%8A%A0%E4%B8%8A%E4%B8%8B%E6%96%87" class="hash-link" aria-label="添加上下文的直接链接" title="添加上下文的直接链接" translate="no">​</a></h4>
<p>你可以在验证装饰其中添加一个自定义的上下文对象，此对象在验证失败时被<code>ValidationError</code>的实例获取</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> validate </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'class-validator'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">MyClass</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	@</span><span class="token function maybe-class-name" style="color:#d73a49">MinLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"EIC code must be at least 32 characters"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token literal-property property" style="color:#36acaa">context</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token literal-property property" style="color:#36acaa">errorCode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1003</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token literal-property property" style="color:#36acaa">developerNote</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"The validated string must contain 32 or more characters."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token literal-property property" style="color:#36acaa">eicCode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> model </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">MyClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">model</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">//errors[0].contexts['minLength'].errorCode === 1003</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="跳过缺失属性">跳过缺失属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%B7%B3%E8%BF%87%E7%BC%BA%E5%A4%B1%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="跳过缺失属性的直接链接" title="跳过缺失属性的直接链接" translate="no">​</a></h4>
<p>有时候你需要跳过一些对象中没有设置的属性，比如更新数据模型时，与创建模型不同的是你只会更新部分值，那么这时候你就需要设置<code>skipMissingProperties</code>为<code>true</code>，当然可能一部分属性是你不想被跳过验证的，那么需要在这些属性上加上<code>@IsDefined()</code>装饰器，加了<code>@IsDefined()</code>装饰器的属性会忽略<code>skipMissingProperties</code>而必定被验证</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">skipMissingProperties</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证组">验证组<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81%E7%BB%84" class="hash-link" aria-label="验证组的直接链接" title="验证组的直接链接" translate="no">​</a></h4>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">validate</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Min</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Length</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"registration"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">age</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Length</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"registration"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"admin"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Alex"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"registration"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 无法通过验证</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"admin"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 可以通过验证</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"registration"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"admin"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 无法通过验证</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 默认模式</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 无法通过验证，因为没有指定group则所有属性都将被验证</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 无法通过验证 (与'groups: undefined'相同)</span><br></span></code></pre></div></div></div></div>
<p>在验证中还有一个<code>always: true</code>选项，如果添加了此选项，无论验证时设定的是哪种模式的<code>groups</code>，都将被验证</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用服务容器">使用服务容器<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E4%BD%BF%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%AE%B9%E5%99%A8" class="hash-link" aria-label="使用服务容器的直接链接" title="使用服务容器的直接链接" translate="no">​</a></h4>
<p>你可以使用服务容器来加载验证器通过依赖注入的方式使用。以下如何将其与<a href="https://github.com/pleerock/typedi" target="_blank" rel="noopener noreferrer" class="">typedi</a>集成的示例：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Container</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"typedi"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">useContainer</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Validator</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// do this somewhere in the global application level:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">useContainer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Container</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> validator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Container</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Validator</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// now everywhere you can inject Validator class which will go from the container</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// also you can inject classes using constructor injection into your custom ValidatorConstraint-s</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="非装饰器验证">非装饰器验证<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%9D%9E%E8%A3%85%E9%A5%B0%E5%99%A8%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="非装饰器验证的直接链接" title="非装饰器验证的直接链接" translate="no">​</a></h4>
<p>如果你的运行环境不支持装饰器请看<a href="https://github.com/typestack/class-validator#defining-validation-schema-without-decorators" target="_blank" rel="noopener noreferrer" class="">这里</a></p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="验证普通对象">验证普通对象<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AA%8C%E8%AF%81%E6%99%AE%E9%80%9A%E5%AF%B9%E8%B1%A1" class="hash-link" aria-label="验证普通对象的直接链接" title="验证普通对象的直接链接" translate="no">​</a></h4>
<blockquote>
<p>Nest.js中使用的验证管道就是class-validator+class-transformer结合的方式</p>
</blockquote>
<p>由于装饰器的性质，必须使用<code>new class()</code>语法实例化待验证的对象。如果你使用了class-validator装饰器定义了类，并且想要验证普通的JS对象（文本对象或JSON.parse返回），则需要将其转换为类实例
（例如，使用<a href="https://github.com/pleerock/class-transformer" target="_blank" rel="noopener noreferrer" class="">class-transformer</a>或仅使用<a href="https://github.com/19majkel94/class-transformer-validator" target="_blank" rel="noopener noreferrer" class="">class-transformer-validator</a>扩展可以为您完成此任务。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义验证">自定义验证<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%87%AA%E5%AE%9A%E4%B9%89%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="自定义验证的直接链接" title="自定义验证的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义规则类">自定义规则类<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E7%B1%BB" class="hash-link" aria-label="自定义规则类的直接链接" title="自定义规则类的直接链接" translate="no">​</a></h4>
<p>你可以创建一个自定义的验证规则的类，并在规则类上添加<code>@ValidatorConstraint</code>装饰器。 还可以设置验证约束名称(<code>name</code>选项)-该名称将在<code>ValidationError</code>中用作“error type”。 如果您不提供约束名称，它将自动生成。</p>
<p>规则类必须实现<code>ValidatorConstraintInterface</code>接口及<code>validate</code>方法，该接口定义了验证逻辑。 如果验证成功，则方法返回<code>true</code>，否则返回<code>false</code>。 自定义验证器可以是异步的，如果您想在执行一些异步操作后执行验证，只需在<code>validate</code>方法中返回带有布尔值的<code>promise</code>。</p>
<p>我们还可以定义了可选方法<code>defaultMessage</code>，它在属性上的装饰器未设置错误消息的情况下定义了默认错误消息。</p>
<p>首选我们创建一个<code>CustomTextLength</code>演示用的验证规则类</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidatorConstraint</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatorConstraintInterface</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationArguments</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">ValidatorConstraint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"customText"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">async</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CustomTextLength</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">implements</span><span class="token plain"> </span><span class="token class-name">ValidatorConstraintInterface</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">text</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">args</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 对于异步验证，您必须在此处返回Promise&lt;boolean&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">defaultMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">args</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 如果验证失败，您可以在此处提供默认错误消息</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Text ($value) is too short or too long!"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>定义好规则后我们就可以在类中使用了</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">CustomTextLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./CustomTextLength"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">CustomTextLength</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Title is too short or long!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">errors</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>你也可以将自定义的约束传入规则类，并通过约束来设定验证的条件</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Validate</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">CustomTextLength</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./CustomTextLength"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">ValidationArguments</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatorConstraint</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatorConstraintInterface</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">ValidatorConstraint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">CustomTextLength</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">implements</span><span class="token plain"> </span><span class="token class-name">ValidatorConstraintInterface</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">text</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">validationArguments</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> validationArguments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constraints</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> validationArguments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constraints</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">CustomTextLength</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Wrong post title"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义装饰器">自定义装饰器<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="自定义装饰器的直接链接" title="自定义装饰器的直接链接" translate="no">​</a></h4>
<p>创建自定义装饰器的方法类似创建自定义规则类，只是使用装饰器而已</p>
<blockquote>
<p>装饰器的详细使用请看我<a href="https://test.3rcd.com/notes/decorator.html" target="_blank" rel="noopener noreferrer" class="">这篇文章</a></p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">registerDecorator</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationOptions</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationArguments</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">IsLongerThan</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">property</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> validationOptions</span><span class="token parameter operator" style="color:#393A34">?</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationOptions</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">object</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter known-class-name class-name">Object</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">propertyName</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">registerDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"isLongerThan"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constructor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> propertyName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">constraints</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">property</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">options</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> validationOptions</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">validator</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">value</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> any</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">args</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">relatedPropertyName</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constraints</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> relatedValue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">object</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">as</span><span class="token plain"> any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">relatedPropertyName</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain">  </span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> value </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"string"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                           </span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> relatedValue </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"string"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                           value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> relatedValue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// you can return a Promise&lt;boolean&gt; here as well, if you want to make async validation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsLongerThan</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"title"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic">/* you can also use additional validation options, like "groups" in your custom validation decorators. "each" is not supported */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Text must be longer than the title"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>在自定义装饰器上仍然可以使用<code>ValidationConstraint</code>装饰器。我们在创建一个<code>IsUserAlreadyExist</code>验证装饰器演示</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">registerDecorator</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationOptions</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatorConstraint</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidatorConstraintInterface</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ValidationArguments</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-validator"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">ValidatorConstraint</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">async</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">IsUserAlreadyExistConstraint</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">implements</span><span class="token plain"> </span><span class="token class-name">ValidatorConstraintInterface</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">validate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">userName</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> any</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">args</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationArguments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token maybe-class-name">UserRepository</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">findOneByName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">user</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">IsUserAlreadyExist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">validationOptions</span><span class="token parameter operator" style="color:#393A34">?</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">ValidationOptions</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">object</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter known-class-name class-name">Object</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">propertyName</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">registerDecorator</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">constructor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">propertyName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> propertyName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">options</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> validationOptions</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">constraints</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">validator</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">IsUserAlreadyExistConstraint</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">IsUserAlreadyExist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token literal-property property" style="color:#36acaa">message</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"User $value already exists. Choose another name."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="同步验证">同步验证<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%90%8C%E6%AD%A5%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="同步验证的直接链接" title="同步验证的直接链接" translate="no">​</a></h4>
<p>如果只是想简单的进行同步验证，可以使用<code>validateSync</code>代替<code>validate</code>。不过需要注意的是<code>validateSync</code>会忽略所有的异步验证。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="class-transfomer中文文档">class-transfomer中文文档<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#class-transfomer%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3" class="hash-link" aria-label="class-transfomer中文文档的直接链接" title="class-transfomer中文文档的直接链接" translate="no">​</a></h2>
<p>类转换器的作用是将普通的javascript对象转换成类对象。我们通过api端点或者json文件访问所得的是普通的json文本，一般我们通过<code>JSON.parse</code>把其转换成普通的javascript对象，但是有时候我们想让它变成一个类的对象而不是普通的javascript对象。比如用<code>class-validator</code>来验证从后端api获取的json字符串时，我们就需要自动把json转为待验证类的对象而不是一个js对象。</p>
<p>例如我们现在可以读取远程api的一个<code>users.json</code>的内容如下</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-json codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-json codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"id"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"firstName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Johny"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"lastName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Cage"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"age"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">27</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"id"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"firstName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Ismoil"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"lastName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Somoni"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"age"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"id"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"firstName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Luke"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"lastName"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Dacascos"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"age"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">12</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre></div></div></div></div>
<p>我们有一个<code>User</code>类</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">age</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">isAdult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">36</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">age</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>然后你想通过<code>user.json</code>来获取<code>User</code>的对象数组</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"users.json"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">users</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">User</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// you can use users here, and type hinting also will be available to you,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">//  but users are not actually instances of User class</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// this means that you can't use methods of User class</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>现在你可以获取<code>users[0].firstname</code>但是由于你获取的是普通的js对象而非<code>User</code>类的对象，所以你无法调用<code>users[0].getName()</code>方法，而<strong>class-transformer</strong>就是为了把普通的js对象按你的需求转换成类对象而生的。</p>
<p>你只要像下面这样就可以创建真正的<code>User[]</code>对象数组了</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"users.json"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">users</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter known-class-name class-name">Object</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> realUsers </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> users</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// now each user in realUsers is instance of User class</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="安装-1">安装<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%AE%89%E8%A3%85-1" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h3>
<ol>
<li class="">
<p>安装class-transformer:
<code>npm install class-transformer --save</code></p>
</li>
<li class="">
<p>安装<code>reflect-metadata</code></p>
<blockquote>
<p>reflect-metadata是必须的，具体使用请看<a class="" href="https://3rcd.com/blog/ts-decorator">这篇博文</a></p>
</blockquote>
</li>
</ol>
<p>安装后在<code>app.ts</code>这种顶层文件你需要<code>import "reflect-metadata";</code></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基础方法">基础方法<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%9F%BA%E7%A1%80%E6%96%B9%E6%B3%95" class="hash-link" aria-label="基础方法的直接链接" title="基础方法的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="plaintoclass">plainToClass<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#plaintoclass" class="hash-link" aria-label="plainToClass的直接链接" title="plainToClass的直接链接" translate="no">​</a></h4>
<p>普通对象转换为类对象</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">plainToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> users </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> userJson</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// to convert user plain object a single user. also supports arrays</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="plaintoclassfromexist">plainToClassFromExist<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#plaintoclassfromexist" class="hash-link" aria-label="plainToClassFromExist的直接链接" title="plainToClassFromExist的直接链接" translate="no">​</a></h4>
<p>普通对象合并已经创建的类实例</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> defaultUser </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">defaultUser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">role</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> mixedUser </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClassFromExist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">defaultUser</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// mixed user should have the value role = user when no value is set otherwise.</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="classtoplain">classToPlain<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#classtoplain" class="hash-link" aria-label="classToPlain的直接链接" title="classToPlain的直接链接" translate="no">​</a></h4>
<p>类实例转换为普通对象</p>
<blockquote>
<p>转换后可以使用<code>JSON.stringify</code>再转成普通的json文本</p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">classToPlain</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">photo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="classtoclass">classToClass<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#classtoclass" class="hash-link" aria-label="classToClass的直接链接" title="classToClass的直接链接" translate="no">​</a></h4>
<p>克隆类实例</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">classToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">photo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>可以使用<code>ignoreDecorators</code>选项去除所有原实例中的装饰器</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="serialize">serialize<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#serialize" class="hash-link" aria-label="serialize的直接链接" title="serialize的直接链接" translate="no">​</a></h4>
<p>直接把类实例转换为json文本,是不是数组都可以转换</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">serialize</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">serialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">photo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="deserialize-和-deserializearray">deserialize 和 deserializeArray<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#deserialize-%E5%92%8C-deserializearray" class="hash-link" aria-label="deserialize 和 deserializeArray的直接链接" title="deserialize 和 deserializeArray的直接链接" translate="no">​</a></h4>
<p>直接把json文本转换为类对象</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">deserialize</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">deserialize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Photo</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> photo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>如果json文本是个对象数组请使用<code>deserializeArray</code>方法</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">deserializeArray</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photos </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">deserializeArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Photo</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> photos</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="强制类型安全">强制类型安全<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8" class="hash-link" aria-label="强制类型安全的直接链接" title="强制类型安全的直接链接" translate="no">​</a></h4>
<p><code>plainToClass</code>会把所有的被转换对象的属性全部类实例的属性，即时类中并不存在某些属性</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">plainToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> fromPlainUser </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">unkownProp</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'hello there'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Umed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Khudoiberdiev'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fromPlainUser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// User {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   unkownProp: 'hello there',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   firstName: 'Umed',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   lastName: 'Khudoiberdiev',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// }</span><br></span></code></pre></div></div></div></div>
<p>你可以使用<code>excludeExtraneousValues</code>选项结合<code>Expose</code>装饰器来指定需要公开的属性</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> plainToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> fromPlainUser </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">unkownProp</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'hello there'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Umed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Khudoiberdiev'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fromPlainUser</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">excludeExtraneousValues</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// User {</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   id: undefined,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   firstName: 'Umed',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//   lastName: 'Khudoiberdiev'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// }</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="子类型转换">子类型转换<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%AD%90%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2" class="hash-link" aria-label="子类型转换的直接链接" title="子类型转换的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="嵌套对象-1">嵌套对象<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%B5%8C%E5%A5%97%E5%AF%B9%E8%B1%A1-1" class="hash-link" aria-label="嵌套对象的直接链接" title="嵌套对象的直接链接" translate="no">​</a></h4>
<p>由于现在Typescript对反射还没有非常好的支持，所以你需要使用<code>@Type</code>装饰器来隐式地指定属性所属的类</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Type</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> plainToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Album</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token maybe-class-name">Photo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">photos</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Photo</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">filename</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> album </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Album</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> albumJson</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// now album is Album object with Photo objects inside</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="多类型选项">多类型选项<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%A4%9A%E7%B1%BB%E5%9E%8B%E9%80%89%E9%A1%B9" class="hash-link" aria-label="多类型选项的直接链接" title="多类型选项的直接链接" translate="no">​</a></h4>
<p>一个嵌套的子类型也可以匹配多个类型，这可以通过判断器实现。判断器需要指定一个<code> property</code>，而被转换js对象中的嵌套对象的也必须拥有与<code>property</code>相同的一个字段，并把值设置为需要转换的子类型的名称。判断器还需要指定所有的子类型值以及其名称，具体示例如下</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Type</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> plainToClass</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> albumJson </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">"id"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">"name"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"foo"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">"topPhoto"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"id"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">9</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"filename"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"cool_wale.jpg"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"depth"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1245</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string-property property" style="color:#36acaa">"__type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"underwater"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> abstract </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">filename</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Landscape</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">panorama</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Portrait</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">person</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Person</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UnderWater</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">depth</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Album</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token maybe-class-name">Photo</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">discriminator</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">property</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"__type"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">subTypes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Landscape</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"landscape"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Portrait</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"portrait"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">UnderWater</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"underwater"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">topPhoto</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Landscape</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token maybe-class-name">Portrait</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token maybe-class-name">UnderWater</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> album </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">Album</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> albumJson</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// now album is Album object with a UnderWater object without `__type` property.</span><br></span></code></pre></div></div></div></div>
<p>此外可以设置<code>keepDiscriminatorProperty: true</code>，这样可以把判断器的属性也包含在转换后的对象中</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="排除与公开">排除与公开<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%8E%92%E9%99%A4%E4%B8%8E%E5%85%AC%E5%BC%80" class="hash-link" aria-label="排除与公开的直接链接" title="排除与公开的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="公开方法的返回值">公开方法的返回值<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%85%AC%E5%BC%80%E6%96%B9%E6%B3%95%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC" class="hash-link" aria-label="公开方法的返回值的直接链接" title="公开方法的返回值的直接链接" translate="no">​</a></h4>
<p>添加<code>@Expose</code>装饰器即可公开getter和方法的返回值</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getFullName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="公开属性为不同名称">公开属性为不同名称<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%85%AC%E5%BC%80%E5%B1%9E%E6%80%A7%E4%B8%BA%E4%B8%8D%E5%90%8C%E5%90%8D%E7%A7%B0" class="hash-link" aria-label="公开属性为不同名称的直接链接" title="公开属性为不同名称的直接链接" translate="no">​</a></h4>
<p>如果要使用其他名称公开某些属性，可以通过为<code>@Expose</code>装饰器指定<code>name</code>选项来实现：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"uid"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"secretKey"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"fullName"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getFullName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="跳过指定属性">跳过指定属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%B7%B3%E8%BF%87%E6%8C%87%E5%AE%9A%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="跳过指定属性的直接链接" title="跳过指定属性的直接链接" translate="no">​</a></h4>
<p>有时您想在转换过程中跳过一些属性。这可以使用<code>@Exclude</code>装饰器完成：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Exclude</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>现在，当您转换用户时，<code>password</code>属性将被跳过，并且不包含在转换结果中。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="根据操作决定跳过">根据操作决定跳过<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%A0%B9%E6%8D%AE%E6%93%8D%E4%BD%9C%E5%86%B3%E5%AE%9A%E8%B7%B3%E8%BF%87" class="hash-link" aria-label="根据操作决定跳过的直接链接" title="根据操作决定跳过的直接链接" translate="no">​</a></h4>
<p>我们可以通过<code>toClassOnly</code>或者<code>toPlainOnly</code>来控制一个属性在哪些操作中需要排除</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Exclude</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">toPlainOnly</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>现在<code>password</code>属性将会在<code>classToPlain</code>操作中排除，相反的可以使用<code>toClassOnly</code></p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="跳过类的所有属性">跳过类的所有属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%B7%B3%E8%BF%87%E7%B1%BB%E7%9A%84%E6%89%80%E6%9C%89%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="跳过类的所有属性的直接链接" title="跳过类的所有属性的直接链接" translate="no">​</a></h4>
<p>你可以通过在类上添加<code>@Exclude</code>装饰器并且在需要公开的属性上添加<code>@Expose</code>装饰器来只公开指定的属性</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Exclude</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>另外，您可以在转换期间设置排除策略：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports">classToPlain</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> photo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">photo</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">strategy</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"excludeAll"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>这时你不需要在添加<code>@Exclude</code>装饰器了</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="跳过私有属性或某些前缀属性">跳过私有属性或某些前缀属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%B7%B3%E8%BF%87%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7%E6%88%96%E6%9F%90%E4%BA%9B%E5%89%8D%E7%BC%80%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="跳过私有属性或某些前缀属性的直接链接" title="跳过私有属性或某些前缀属性的直接链接" translate="no">​</a></h4>
<p>我们可以排除公开具有指定前缀的属性以及私有属性</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">_firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">_lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">_password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">setName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">firstName</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">lastName</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> firstName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_lastName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">" "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">id</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Johny"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Cage"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_password</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">123</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> plainUser </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">excludePrefixes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"_"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// here plainUser will be equal to</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// { id: 1, name: "Johny Cage" }</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用组来控制排除的属性">使用组来控制排除的属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E4%BD%BF%E7%94%A8%E7%BB%84%E6%9D%A5%E6%8E%A7%E5%88%B6%E6%8E%92%E9%99%A4%E7%9A%84%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="使用组来控制排除的属性的直接链接" title="使用组来控制排除的属性的直接链接" translate="no">​</a></h4>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Exclude</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"admin"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// this means that this data will be exposed only to users and admins</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// this means that this data will be exposed only to users</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id, name, email and password</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"admin"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id, name and email</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用版本范围来控制公开和排除的属性">使用版本范围来控制公开和排除的属性<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E4%BD%BF%E7%94%A8%E7%89%88%E6%9C%AC%E8%8C%83%E5%9B%B4%E6%9D%A5%E6%8E%A7%E5%88%B6%E5%85%AC%E5%BC%80%E5%92%8C%E6%8E%92%E9%99%A4%E7%9A%84%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="使用版本范围来控制公开和排除的属性的直接链接" title="使用版本范围来控制公开和排除的属性的直接链接" translate="no">​</a></h4>
<p>如果要构建具有不同版本的API，则class-transformer具有非常有用的工具。您可以控制应在哪个版本中公开或排除模型的哪些属性。示例</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Exclude</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Expose</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">since</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.7</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">until</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// this means that this property will be exposed for version starting from 0.7 until 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">since</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2.1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// this means that this property will be exposed for version starting from 2.1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">version</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.5</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id and name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">version</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.7</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id, name and email</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user3 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">version</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id and name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user4 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">version</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id and name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> user5 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">classToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">version</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2.1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// will contain id, name nad password</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="特殊处理">特殊处理<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E7%89%B9%E6%AE%8A%E5%A4%84%E7%90%86" class="hash-link" aria-label="特殊处理的直接链接" title="特殊处理的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="将日期字符串转换为date对象">将日期字符串转换为Date对象<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%B0%86%E6%97%A5%E6%9C%9F%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%8D%A2%E4%B8%BAdate%E5%AF%B9%E8%B1%A1" class="hash-link" aria-label="将日期字符串转换为Date对象的直接链接" title="将日期字符串转换为Date对象的直接链接" translate="no">​</a></h4>
<p>有时，您的JavaScript对象中有一个以字符串格式接收的Date。您想从中创建一个真正的javascript Date对象。您只需将Date对象传递给<code>@Type</code>装饰器即可完成此操作：</p>
<blockquote>
<p>当从类对象反向转换为普通对象时registrationDate将会被转回为字符串</p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Type</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">registrationDate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>当您想将值转换为<code>Number</code>, <code>String</code>, <code>Boolean</code> 类型时也是这样做</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="数组处理">数组处理<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E6%95%B0%E7%BB%84%E5%A4%84%E7%90%86" class="hash-link" aria-label="数组处理的直接链接" title="数组处理的直接链接" translate="no">​</a></h4>
<p>当你想转换数组时，你必须使用<code>@Type</code>装饰器指定数组项的类型也可以使用自定义的数组类型</p>
<p><code>Set</code>和<code>Map</code>也是一样</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Type</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AlbumCollection</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Array</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Album</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// custom array functions ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token maybe-class-name">Album</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">albums</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Album</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// albums: AlbumCollection; 使用自定义类型</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Skill</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Weapon</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">range</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Player</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token maybe-class-name">Skill</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">skills</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Set</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Skill</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token maybe-class-name">Weapon</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">weapons</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Map</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">Weapon</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义转换">自定义转换<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%BD%AC%E6%8D%A2" class="hash-link" aria-label="自定义转换的直接链接" title="自定义转换的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本使用-1">基本使用<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-1" class="hash-link" aria-label="基本使用的直接链接" title="基本使用的直接链接" translate="no">​</a></h4>
<p>你可以使用<code>@Transform</code>添加额外的数据转换,例如当你想把通过普通对象中的字符串日期转换后的<code>date</code>对象继续转换变成<code>moment</code>库的对象：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Transform</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"class-transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports operator" style="color:#393A34">*</span><span class="token imports"> </span><span class="token imports keyword module" style="color:#00009f">as</span><span class="token imports"> moment</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"moment"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports maybe-class-name">Moment</span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"moment"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Photo</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Type</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Transform</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">value</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">moment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">toClassOnly</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">date</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Moment</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>现在当执行<code>plainToClass</code>转换后的对象中的<code>date</code>属性将是一个<code>Moment</code>对象。<code>@Transform</code>同样支持组和版本。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="高级用法">高级用法<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95" class="hash-link" aria-label="高级用法的直接链接" title="高级用法的直接链接" translate="no">​</a></h4>
<p><code>@Transform</code>有更多的参数给你创建自定义的转换逻辑</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">Transform</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">value</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> obj</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> type</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<table><thead><tr><th style="text-align:left">参数</th><th>描述</th></tr></thead><tbody><tr><td style="text-align:left"><code>value</code></td><td>自定义转换执行前的属性值</td></tr><tr><td style="text-align:left"><code>obj</code></td><td>转换源对象</td></tr><tr><td style="text-align:left"><code>type</code></td><td>转换的类型</td></tr></tbody></table>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="其他装饰器">其他装饰器<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%85%B6%E4%BB%96%E8%A3%85%E9%A5%B0%E5%99%A8" class="hash-link" aria-label="其他装饰器的直接链接" title="其他装饰器的直接链接" translate="no">​</a></h4>
<table><thead><tr><th>签名</th><th>示例</th></tr></thead><tbody><tr><td><code>@TransformClassToPlain</code></td><td><code>@TransformClassToPlain({ groups: ["user"] })</code></td></tr><tr><td><code>@TransformClassToClass</code></td><td><code>@TransformClassToClass({ groups: ["user"] })</code></td></tr><tr><td><code>@TransformPlainToClas</code></td><td><code>@TransformPlainToClass(User, { groups: ["user"] })</code></td></tr></tbody></table>
<p>上述装饰器接受一个可选参数：<code>ClassTransformOptions</code>-转换选项，例如groups, version, name，示例：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">@</span><span class="token function maybe-class-name" style="color:#d73a49">Exclude</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">Expose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'user.email'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">email</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">UserController</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    @</span><span class="token function maybe-class-name" style="color:#d73a49">TransformClassToPlain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">groups</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'user.email'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">getUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">User</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">firstName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Snir"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">lastName</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Segal"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">password</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"imnosuperman"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> controller </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">UserController</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> controller</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p><code>user</code>对象将包含firstname,latstname和email</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用泛型">使用泛型<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E4%BD%BF%E7%94%A8%E6%B3%9B%E5%9E%8B" class="hash-link" aria-label="使用泛型的直接链接" title="使用泛型的直接链接" translate="no">​</a></h4>
<p>由于目前Typescript对反射的支持还没有完善，所以只能使用其它替代方案，具体可以查看<a href="https://github.com/pleerock/class-transformer/tree/master/sample/sample4-generics" target="_blank" rel="noopener noreferrer" class="">这个例子</a></p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="隐式类型转换">隐式类型转换<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E9%9A%90%E5%BC%8F%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2" class="hash-link" aria-label="隐式类型转换的直接链接" title="隐式类型转换的直接链接" translate="no">​</a></h4>
<blockquote>
<p>你如果将class-validator与class-transformer一起使用，则可能不想启用此功能。</p>
</blockquote>
<p>根据Typescript提供的类型信息，启用内置类型之间的自动转换。默认禁用。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">IsString</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'class-validator'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">MyPayload</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  @</span><span class="token function maybe-class-name" style="color:#d73a49">IsString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">prop</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> result1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">MyPayload</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">prop</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1234</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">enableImplicitConversion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> result2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">plainToClass</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">MyPayload</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">prop</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1234</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">enableImplicitConversion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *  result1 will be `</span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> prop: "1234" </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic">` - notice how the prop value has been converted to string.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *  result2 will be `</span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> prop: 1234 </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic">` - default behaviour</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="循环引用">循环引用<a href="https://3rcd.com/blog/class-validator-and-class-transformer-cn#%E5%BE%AA%E7%8E%AF%E5%BC%95%E7%94%A8" class="hash-link" aria-label="循环引用的直接链接" title="循环引用的直接链接" translate="no">​</a></h4>
<p>如果<code>User</code>包含一个<code>Photo</code>类型的<code>photos</code>数组属性，而<code>Photo</code>又包含一个属性链接到<code>User</code>，则转换过程中此属性会被忽略，除了<code>classToClass</code>操作。</p>]]></content:encoded>
            <category>class-validator</category>
            <category>class-transformer</category>
            <category>typescript</category>
            <category>nestjs</category>
        </item>
        <item>
            <title><![CDATA[commanderjs中文文档]]></title>
            <link>https://3rcd.com/blog/commanderjs-usage</link>
            <guid>https://3rcd.com/blog/commanderjs-usage</guid>
            <pubDate>Tue, 21 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[node.js 命令行接口的完整解决方案，灵感来自 Ruby 的 commander。]]></description>
            <content:encoded><![CDATA[<p><a href="http://nodejs.org/" target="_blank" rel="noopener noreferrer" class="">node.js</a> 命令行接口的完整解决方案，灵感来自 Ruby 的 <a href="https://github.com/commander-rb/commander" target="_blank" rel="noopener noreferrer" class="">commander</a>。<br>
<a href="http://tj.github.com/commander.js/" target="_blank" rel="noopener noreferrer" class="">API 文档</a></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="安装">安装<a href="https://3rcd.com/blog/commanderjs-usage#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h2>
<p>$ npm install commander</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="声明program变量">声明program变量<a href="https://3rcd.com/blog/commanderjs-usage#%EF%BF%BD%E5%A3%B0%E6%98%8Eprogram%E5%8F%98%E9%87%8F" class="hash-link" aria-label="声明program变量的直接链接" title="声明program变量的直接链接" translate="no">​</a></h2>
<p>Commander为了方便快速编程导出了一个全局对象。为简洁起见，本README中的示例中使用了它。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>对于可能以多种方式使用commander的大型程序，包括单元测试，最好创建一个本地Command对象来使用。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> commander </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">commander</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">Command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="选项">选项<a href="https://3rcd.com/blog/commanderjs-usage#%E9%80%89%E9%A1%B9" class="hash-link" aria-label="选项的直接链接" title="选项的直接链接" translate="no">​</a></h2>
<p><code>.option()</code> 方法用来定义带选项的 commander，同时也用于这些选项的文档。每个选项可以有一个短标识(单个字符)和一个长名字，它们之间用逗号或空格分开。</p>
<p>选项会被放到 Commander 对象的属性上，多词选项如"--template-engine"会被转为驼峰法<code>program.templateEngine</code>。多个短标识可以组合为一个参数，如<code>-a -b -c</code>等价于<code>-abc</code>。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="常用选项类型boolean和值">常用选项类型，boolean和值<a href="https://3rcd.com/blog/commanderjs-usage#%E5%B8%B8%E7%94%A8%E9%80%89%E9%A1%B9%E7%B1%BB%E5%9E%8Bboolean%E5%92%8C%E5%80%BC" class="hash-link" aria-label="常用选项类型，boolean和值的直接链接" title="常用选项类型，boolean和值的直接链接" translate="no">​</a></h3>
<p>最常用的两个选项类型是boolean(选项后面不跟值)和选项跟一个值（使用尖括号声明）。除非在命令行中指定，否则两者都是<code>undefined</code>。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-d, --debug'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'output extra debugging'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-s, --small'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'small pizza size'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-p, --pizza-type &lt;type&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'flavour of pizza'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">debug</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">opts</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'pizza details:'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">small</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'- small pizza size'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pizzaType</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">- </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">pizzaType</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options -d</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{ debug: true, small: undefined, pizzaType: undefined }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pizza details:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options -p</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">error: option `-p, --pizza-type &lt;type&gt;' argument missing</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options -ds -p vegetarian</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">{ debug: true, small: true, pizzaType: 'vegetarian' }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pizza details:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- small pizza size</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- vegetarian</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options --pizza-type=cheese</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pizza details:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- cheese</span><br></span></code></pre></div></div></div></div>
<p><code>program.parse(arguments)</code>会处理参数，没有被使用的选项会被存放在<code>program.args</code>数组中。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="默认选项值">默认选项值<a href="https://3rcd.com/blog/commanderjs-usage#%E9%BB%98%E8%AE%A4%E9%80%89%E9%A1%B9%E5%80%BC" class="hash-link" aria-label="默认选项值的直接链接" title="默认选项值的直接链接" translate="no">​</a></h3>
<p>可以为选项设置一个默认值。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-c, --cheese &lt;type&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'add the specified type of cheese'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'blue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">cheese: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">cheese</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cheese: blue</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options --cheese stilton</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cheese: stilton</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="其他选项类型可忽略的布尔值和标志值">其他选项类型，可忽略的布尔值和标志值<a href="https://3rcd.com/blog/commanderjs-usage#%E5%85%B6%E4%BB%96%E9%80%89%E9%A1%B9%E7%B1%BB%E5%9E%8B%E5%8F%AF%E5%BF%BD%E7%95%A5%E7%9A%84%E5%B8%83%E5%B0%94%E5%80%BC%E5%92%8C%E6%A0%87%E5%BF%97%E5%80%BC" class="hash-link" aria-label="其他选项类型，可忽略的布尔值和标志值的直接链接" title="其他选项类型，可忽略的布尔值和标志值的直接链接" translate="no">​</a></h3>
<p>选项的值为 boolean 类型时，可以在其长名字前加<code>no-</code>使默认值为true，如果传了这个选项则值为false。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-n, --no-sauce'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Remove sauce'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">sauce</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'you ordered a pizza with sauce'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'you ordered a pizza without sauce'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">you ordered a pizza with sauce</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options --sauce</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">error: unknown option `--sauce'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ pizza-options --no-sauce</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">you ordered a pizza without sauce</span><br></span></code></pre></div></div></div></div>
<p>您可以指定一个用作标志的选项，它可以接受值（使用方括号声明，即传值不是必须的）。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-c, --cheese [type]'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Add cheese with optional type'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">cheese</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'no cheese'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">cheese</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'add cheese'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">add cheese type </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">cheese</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义选项处理">自定义选项处理<a href="https://3rcd.com/blog/commanderjs-usage#%E8%87%AA%E5%AE%9A%E4%B9%89%E9%80%89%E9%A1%B9%E5%A4%84%E7%90%86" class="hash-link" aria-label="自定义选项处理的直接链接" title="自定义选项处理的直接链接" translate="no">​</a></h2>
<p>你可以指定一个函数来处理选项的值，接收两个参数：用户传入的值、上一个值(previous value)，它会返回新的选项值。</p>
<p>你可以将选项值强制转换为所需类型，或累积值，或完全自定义处理。</p>
<p>你可以在函数后面指定选项的默认或初始值。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">myParseInt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">value</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> dummyPrevious</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// parseInt takes a string and an optional radix</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">parseInt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">increaseVerbosity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">dummyValue</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> previous</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> previous </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">collect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">value</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> previous</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> previous</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">concat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">commaSeparatedList</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">value</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> dummyPrevious</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">split</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">','</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-f, --float &lt;number&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'float argument'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parseFloat</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-i, --integer &lt;number&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'integer argument'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> myParseInt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-v, --verbose'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'verbosity that can be increased'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> increaseVerbosity</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-c, --collect &lt;value&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'repeatable value'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> collect</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-l, --list &lt;items&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'comma separated list'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> commaSeparatedList</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">float</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">float: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">float</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">integer</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">integer: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">integer</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">verbose</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">verbosity: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">program</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">verbose</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">collect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">collect</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">list</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ custom -f 1e2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">float: 100</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ custom --integer 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">integer: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ custom -v -v -v</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">verbose: 3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ custom -c a -c b -c c</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[ 'a', 'b', 'c' ]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">$ custom --list x,y,z</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[ 'x', 'y', 'z' ]</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="版本选项">版本选项<a href="https://3rcd.com/blog/commanderjs-usage#%E7%89%88%E6%9C%AC%E9%80%89%E9%A1%B9" class="hash-link" aria-label="版本选项的直接链接" title="版本选项的直接链接" translate="no">​</a></h3>
<p><code>version</code>方法会处理显示版本命令，默认选项标识为<code>-V</code>和<code>--version</code>，当存在时会打印版本号并退出。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">    program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">    $ ./examples/pizza -V</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    0.0.1</span><br></span></code></pre></div></div></div></div>
<p>你可以自定义标识，通过给<code>version</code>方法再传递一个参数，语法给<code>option</code>方法一致。版本标识名字可以是任意的，但是必须要有长名字。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">program.version('0.0.1', '-v, --version');</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="指定命令选项">指定命令选项<a href="https://3rcd.com/blog/commanderjs-usage#%E6%8C%87%E5%AE%9A%E5%91%BD%E4%BB%A4%E9%80%89%E9%A1%B9" class="hash-link" aria-label="指定命令选项的直接链接" title="指定命令选项的直接链接" translate="no">​</a></h2>
<p>可以给命令绑定选项。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token hashbang comment" style="color:#999988;font-style:italic">#!/usr/bin/env node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'rm &lt;dir&gt;'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-r, --recursive'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Remove recursively'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">dir</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> cmd</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'remove '</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> dir </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cmd</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">recursive</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">' recursively'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<p>使用该命令时，将验证命令的选项。任何未知选项都将报告为错误。但是，如果基于操作的命令没有定义action，则不验证选项。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="正则表达式">正则表达式<a href="https://3rcd.com/blog/commanderjs-usage#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F" class="hash-link" aria-label="正则表达式的直接链接" title="正则表达式的直接链接" translate="no">​</a></h2>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.1.0'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-s --size &lt;size&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Pizza size'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token regex regex-delimiter" style="color:#36acaa">/</span><span class="token regex regex-source language-regex anchor function" style="color:#d73a49">^</span><span class="token regex regex-source language-regex group punctuation" style="color:#393A34">(</span><span class="token regex regex-source language-regex" style="color:#36acaa">large</span><span class="token regex regex-source language-regex alternation keyword" style="color:#00009f">|</span><span class="token regex regex-source language-regex" style="color:#36acaa">medium</span><span class="token regex regex-source language-regex alternation keyword" style="color:#00009f">|</span><span class="token regex regex-source language-regex" style="color:#36acaa">small</span><span class="token regex regex-source language-regex group punctuation" style="color:#393A34">)</span><span class="token regex regex-source language-regex anchor function" style="color:#d73a49">$</span><span class="token regex regex-delimiter" style="color:#36acaa">/</span><span class="token regex regex-flags" style="color:#36acaa">i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'medium'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-d --drink [drink]'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Drink'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token regex regex-delimiter" style="color:#36acaa">/</span><span class="token regex regex-source language-regex anchor function" style="color:#d73a49">^</span><span class="token regex regex-source language-regex group punctuation" style="color:#393A34">(</span><span class="token regex regex-source language-regex" style="color:#36acaa">coke</span><span class="token regex regex-source language-regex alternation keyword" style="color:#00009f">|</span><span class="token regex regex-source language-regex" style="color:#36acaa">pepsi</span><span class="token regex regex-source language-regex alternation keyword" style="color:#00009f">|</span><span class="token regex regex-source language-regex" style="color:#36acaa">izze</span><span class="token regex regex-source language-regex group punctuation" style="color:#393A34">)</span><span class="token regex regex-source language-regex anchor function" style="color:#d73a49">$</span><span class="token regex regex-delimiter" style="color:#36acaa">/</span><span class="token regex regex-flags" style="color:#36acaa">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">' size: %j'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">' drink: %j'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">drink</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>注：上面代码如果size选项传入的值和正则不匹配，则值为medium(默认值)。drink选项和正则不匹配，值为true。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="可变参数">可变参数<a href="https://3rcd.com/blog/commanderjs-usage#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0" class="hash-link" aria-label="可变参数的直接链接" title="可变参数的直接链接" translate="no">​</a></h2>
<p>一个命令的最后一个参数可以是可变参数, 并且只有最后一个参数可变。为了使参数可变，你需要在参数名后面追加 <code>...</code>。 下面是个示例：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token hashbang comment" style="color:#999988;font-style:italic">#!/usr/bin/env node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * Module dependencies.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'rmdir &lt;dir&gt; [otherDirs...]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">dir</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> otherDirs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'rmdir %s'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dir</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">otherDirs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      otherDirs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">oDir</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'rmdir %s'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> oDir</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>可变参数的值以 <code>数组</code> 的形式保存。如上所示，在传递给你的 action 的参数和 <code>program.args</code> 中的值都是如此。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="指定参数的语法">指定参数的语法<a href="https://3rcd.com/blog/commanderjs-usage#%E6%8C%87%E5%AE%9A%E5%8F%82%E6%95%B0%E7%9A%84%E8%AF%AD%E6%B3%95" class="hash-link" aria-label="指定参数的语法的直接链接" title="指定参数的语法的直接链接" translate="no">​</a></h2>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token hashbang comment" style="color:#999988;font-style:italic">#!/usr/bin/env node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'../'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">arguments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'&lt;cmd&gt; [env]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cmd</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     cmdValue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> cmd</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     envValue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> cmdValue </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'undefined'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'no command given!'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">exit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'command:'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cmdValue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'environment:'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> envValue </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"no environment given"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>尖括号（例如 <code>&lt;cmd&gt;</code>）代表必填输入，方括号（例如 <code>[env]</code>）代表可选输入。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="git-风格的子命令">Git 风格的子命令<a href="https://3rcd.com/blog/commanderjs-usage#git-%E9%A3%8E%E6%A0%BC%E7%9A%84%E5%AD%90%E5%91%BD%E4%BB%A4" class="hash-link" aria-label="Git 风格的子命令的直接链接" title="Git 风格的子命令的直接链接" translate="no">​</a></h2>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// file: ./examples/pm</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'..'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'install [name]'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'install one or more packages'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'search [query]'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'search with optional query'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'list'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'list packages installed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">isDefault</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>当 <code>.command()</code> 带有描述参数时，不能采用 <code>.action(callback)</code> 来处理子命令，否则会出错。这告诉 commander，你将采用单独的可执行文件作为子命令，就像 <code>git(1)</code> 和其他流行的工具一样。
Commander 将会尝试在入口脚本（例如 <code>./examples/pm</code>）的目录中搜索 <code>program-command</code> 形式的可执行文件，例如 <code>pm-install</code>, <code>pm-search</code>。</p>
<p>你可以在调用 <code>.command()</code> 时传递选项。指定 <code>opts.noHelp</code> 为 <code>true</code> 将从生成的帮助输出中剔除该选项。指定 <code>opts.isDefault</code> 为 <code>true</code> 将会在没有其它子命令指定的情况下，执行该子命令。</p>
<p>如果你打算全局安装该命令，请确保可执行文件有对应的权限，例如 <code>755</code></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="--harmony"><code>--harmony</code><a href="https://3rcd.com/blog/commanderjs-usage#--harmony" class="hash-link" aria-label="--harmony的直接链接" title="--harmony的直接链接" translate="no">​</a></h3>
<p>您可以采用两种方式启用 <code>--harmony</code>：</p>
<ul>
<li class="">在子命令脚本中加上 <code>#!/usr/bin/env node --harmony</code>。注意一些系统版本不支持此模式。</li>
<li class="">在指令调用时加上 <code>--harmony</code> 参数，例如 <code>node --harmony examples/pm publish --harmony</code> 选项在开启子进程时会被保留。</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自动化帮助信息---help">自动化帮助信息 --help<a href="https://3rcd.com/blog/commanderjs-usage#%E8%87%AA%E5%8A%A8%E5%8C%96%E5%B8%AE%E5%8A%A9%E4%BF%A1%E6%81%AF---help" class="hash-link" aria-label="自动化帮助信息 --help的直接链接" title="自动化帮助信息 --help的直接链接" translate="no">​</a></h2>
<p>帮助信息是 commander 基于你的程序自动生成的，下面是 <code>--help</code> 生成的帮助信息：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ ./examples/pizza --help</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Usage: pizza [options]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">An application for pizzas ordering</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Options:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -h, --help           output usage information</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -V, --version        output the version number</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -p, --peppers        Add peppers</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -P, --pineapple      Add pineapple</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -b, --bbq            Add bbq sauce</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -c, --cheese &lt;type&gt;  Add the specified type of cheese [marble]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -C, --no-cheese      You do not want any cheese</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义帮助">自定义帮助<a href="https://3rcd.com/blog/commanderjs-usage#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B8%AE%E5%8A%A9" class="hash-link" aria-label="自定义帮助的直接链接" title="自定义帮助的直接链接" translate="no">​</a></h2>
<p>你可以通过监听 <code>--help</code> 来控制 <code>-h, --help</code> 显示任何信息。一旦调用完成， Commander 将自动退出，你的程序的其余部分不会展示。例如在下面的 “stuff” 将不会在执行 <code>--help</code> 时输出。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token hashbang comment" style="color:#999988;font-style:italic">#!/usr/bin/env node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * Module dependencies.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-f, --foo'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'enable some foo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-b, --bar'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'enable some bar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-B, --baz'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'enable some baz'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// must be before .parse() since</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// node's emit() is immediate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'--help'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Examples:'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'  $ custom-help --help'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'  $ custom-help -h'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'stuff'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>下列帮助信息是运行 <code>node script-name.js -h</code> or <code>node script-name.js --help</code> 时输出的:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">Usage: custom-help [options]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Options:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -h, --help     output usage information</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -V, --version  output the version number</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -f, --foo      enable some foo</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -b, --bar      enable some bar</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  -B, --baz      enable some baz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Examples:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  $ custom-help --help</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  $ custom-help -h</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="outputhelpcb">.outputHelp(cb)<a href="https://3rcd.com/blog/commanderjs-usage#outputhelpcb" class="hash-link" aria-label=".outputHelp(cb)的直接链接" title=".outputHelp(cb)的直接链接" translate="no">​</a></h2>
<p>不退出输出帮助信息。
可选的回调可在显示帮助文本后处理。
如果你想显示默认的帮助（例如，如果没有提供命令），你可以使用类似的东西：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> colors </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'colors'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'getstream [url]'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'get stream URL'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">slice</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">outputHelp</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">make_red</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make_red</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">txt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> colors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">red</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">txt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 在控制台上显示红色的帮助文本</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="helpcb">.help(cb)<a href="https://3rcd.com/blog/commanderjs-usage#helpcb" class="hash-link" aria-label=".help(cb)的直接链接" title=".help(cb)的直接链接" translate="no">​</a></h2>
<p>输出帮助信息并立即退出。
可选的回调可在显示帮助文本后处理。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="自定义事件监听">自定义事件监听<a href="https://3rcd.com/blog/commanderjs-usage#%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC" class="hash-link" aria-label="自定义事件监听的直接链接" title="自定义事件监听的直接链接" translate="no">​</a></h2>
<p>你可以通过监听命令和选项来执行自定义函数。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 当有选项verbose时会执行函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'option:verbose'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">VERBOSE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">verbose</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 未知命令会报错</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'command:*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Invalid command: %s\nSee --help for a list of available commands.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">' '</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">exit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="零碎知识">零碎知识<a href="https://3rcd.com/blog/commanderjs-usage#%E9%9B%B6%E7%A2%8E%E7%9F%A5%E8%AF%86" class="hash-link" aria-label="零碎知识的直接链接" title="零碎知识的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="typescript">TypeScript<a href="https://3rcd.com/blog/commanderjs-usage#typescript" class="hash-link" aria-label="TypeScript的直接链接" title="TypeScript的直接链接" translate="no">​</a></h3>
<p>包里包含 TypeScript 定义文件，但是需要你自己安装 node types。如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-bash codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-bash codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">npm install commander</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">npm install --save-dev @types/node</span><br></span></code></pre></div></div></div></div>
<p>如果你使用 <code>ts-node</code> 和 git风格子命令编写 <code>.ts</code> 文件, 你需要使用 node 来执行程序以保证正确执行子命令。如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-bash codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-bash codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">node -r ts-node/register pm.ts</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="例子">例子<a href="https://3rcd.com/blog/commanderjs-usage#%E4%BE%8B%E5%AD%90" class="hash-link" aria-label="例子的直接链接" title="例子的直接链接" translate="no">​</a></h2>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> program </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'commander'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">version</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'0.0.1'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-C, --chdir &lt;path&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'change the working directory'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-c, --config &lt;path&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'set config path. defaults to ./deploy.conf'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'-T, --no-tests'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'ignore test hook'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'setup [env]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">description</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'run setup commands for all envs'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"-s, --setup_mode [mode]"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Which setup mode to use"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">env</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> options</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> mode </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> options</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">setup_mode</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"normal"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    env </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> env </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'all'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'setup for %s env(s) with %s mode'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> mode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'exec &lt;cmd&gt;'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">alias</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'ex'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">description</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'execute the given remote cmd'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">option</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"-e, --exec_mode &lt;mode&gt;"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Which exec mode to use"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cmd</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> options</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'exec "%s" using %s mode'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cmd</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> options</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">exec_mode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'--help'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Examples:'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'  $ deploy exec sequential'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'  $ deploy exec async'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">command</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'deploying "%s"'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">program</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">argv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>更多的 <a href="https://github.com/tj/commander.js/tree/master/examples" target="_blank" rel="noopener noreferrer" class="">演示</a> 可以在这里找到。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="许可证">许可证<a href="https://3rcd.com/blog/commanderjs-usage#%E8%AE%B8%E5%8F%AF%E8%AF%81" class="hash-link" aria-label="许可证的直接链接" title="许可证的直接链接" translate="no">​</a></h2>
<p><a href="https://github.com/tj/commander.js/blob/master/LICENSE" target="_blank" rel="noopener noreferrer" class="">MIT</a></p>]]></content:encoded>
            <category>comannderjs</category>
            <category>typescript</category>
            <category>node</category>
            <category>cli</category>
        </item>
        <item>
            <title><![CDATA[老版本Bull使用教程]]></title>
            <link>https://3rcd.com/blog/bull-usage</link>
            <guid>https://3rcd.com/blog/bull-usage</guid>
            <pubDate>Mon, 20 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[基本概念]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本概念">基本概念<a href="https://3rcd.com/blog/bull-usage#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5" class="hash-link" aria-label="基本概念的直接链接" title="基本概念的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="bull是什么">Bull是什么?<a href="https://3rcd.com/blog/bull-usage#bull%E6%98%AF%E4%BB%80%E4%B9%88" class="hash-link" aria-label="Bull是什么?的直接链接" title="Bull是什么?的直接链接" translate="no">​</a></h3>
<blockquote>
<p>任务列队一般用于异步处理视频转码,发送短信等耗时任务,不至于API接口连接卡死</p>
</blockquote>
<p>Bull是一个Node库，它基于 <a href="https://redis.io/" target="_blank" rel="noopener noreferrer" class="">redis</a>实现了快速而强大的队列系统。</p>
<p>尽管可以使用Redis命令直接实现队列，但是该库提供了一个API，该API可以处理所有底层细节并丰富了Redis基本功能，因此可以轻松处理更复杂的用例。</p>
<p>如果您不熟悉队列，您可能会想知道为什么需要它。队列可以用一种优雅的方式解决许多不同的问题，比如在微服务之间创建健壮的通信通道来平滑地处理CPU高峰，或将繁重的工作从一台服务器转移到许多较小的工作区间等。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="开始">开始<a href="https://3rcd.com/blog/bull-usage#%E5%BC%80%E5%A7%8B" class="hash-link" aria-label="开始的直接链接" title="开始的直接链接" translate="no">​</a></h3>
<p>安装Bull:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ npm install bull --save &amp;&amp; npm install @types/bull --save-dev</span><br></span></code></pre></div></div></div></div>
<p>或者</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">$ yarn add bull &amp;&amp; yarn add --dev @types/bull</span><br></span></code></pre></div></div></div></div>
<p>为了使用bull,你必须先安装Redis.在本地开发环境使用<a href="https://hub.docker.com/_/redis/" target="_blank" rel="noopener noreferrer" class="">docker</a>可以方便的安装.Bull默认使用 <code>localhost:6379</code>来连接Redis.</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="简单列队">简单列队<a href="https://3rcd.com/blog/bull-usage#%E7%AE%80%E5%8D%95%E5%88%97%E9%98%9F" class="hash-link" aria-label="简单列队的直接链接" title="简单列队的直接链接" translate="no">​</a></h4>
<p>只需通过实例化Bull实例即可创建队列:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myFirstQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Bull</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'my-first-queue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>一个队列实例通常可以有 3 个主要不同的角色：任务生产者、任务消费者或以及事件监听器。</p>
<p>尽管一个给定的实例可用于 3 个角色，但通常生产者和消费者被创建为为多个实例。通过给定队列的例化名称（如上面的示例中的<code>my-first-queue</code>）来引用它，一个列队可以具有许多生产者、许多使用者和许多侦听器。一个重要的方面是，生产者可以添加任务到队列，即使当时没有可用的消费者：队列提供异步通信，这是使它们如此强大的功能之一。</p>
<p>相反，您可以让一个或多个消费者使用队列中的任务，这些任务将按指定顺序消费任务：FIFO（默认值）、FIFO 或根据优先级消费任务。</p>
<p>关于工作区间，它们可以在同一个或不同的进程中、在同一台计算机或群集中运行。Redis 将作为一个公共端点，只要消费者或生产者可以连接到 Redis，他们将能够合作处理任务。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="生产者">生产者<a href="https://3rcd.com/blog/bull-usage#%E7%94%9F%E4%BA%A7%E8%80%85" class="hash-link" aria-label="生产者的直接链接" title="生产者的直接链接" translate="no">​</a></h4>
<p>任务生产者只是将任务添加到队列的一些Node程序，如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myFirstQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Bull</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'my-first-queue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> job </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> myFirstQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>如您所看到的，任务只是一个 javascript 对象。此对象必须可被序列化，更具体地说应该可以被<code>JSON.stringify</code>转化为字符串，因为这就是它存储在 Redis 中的形式。</p>
<p>也可以在任务数据对象参数之后提供一个选项对象参数，后面我们将介绍这一点。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="消费者">消费者<a href="https://3rcd.com/blog/bull-usage#%E6%B6%88%E8%B4%B9%E8%80%85" class="hash-link" aria-label="消费者的直接链接" title="消费者的直接链接" translate="no">​</a></h4>
<p>消费者或工作区间，只不过是一个Node程序，它定义了一个流程函数，如：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myFirstQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Bull</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'my-first-queue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">myFirstQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">doSomething</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>每次工作区间空闲且队列中有任务被等待处理时，都会调用该任务的<code>process</code>函数。由于添加任务时消费者不需要在线(添加和消费是异步的)，因此会有许多任务堆积在队列中等待消费，直到全部处理完。</p>
<p>在上面的示例中，我们将<code>process</code>函数定义为 <code>async</code>，这是强烈建议的定义方法。如果您的 Node 运行时不支持异步/等待，那么您只需在进程函数的末尾返回一个<code>Promise</code>，以取得类似的结果。</p>
<p><code>process</code>函数返回的值将存储在任务<code>job</code>实例中，方便后面可以访问，例如在监听器的<code>completed</code>事件中可以通过<code>progress</code>函数来访问<code>job</code>实例：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">myFirstQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> progress </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">doSomething</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    progress </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">progress</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">progress</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="监听器">监听器<a href="https://3rcd.com/blog/bull-usage#%E7%9B%91%E5%90%AC%E5%99%A8" class="hash-link" aria-label="监听器的直接链接" title="监听器的直接链接" translate="no">​</a></h4>
<p>最后，您可以监听队列中触发的事件。如果是本地监听器则只接收在指定的队列实例中生成的通知，如果是全局监听器就会监听指定队列的所有事件。因此，您可以将监听器添加到任何实例，甚至充当消费者或生产者的实例。但请注意，如果队列不是消费者或生产者，则本地事件永远不会触发，在这种情况下，您需要使用全局事件。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myFirstQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Bull</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'my-first-queue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Define a local completed event</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">myFirstQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'completed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Job completed with result </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">result</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="生命周期">生命周期<a href="https://3rcd.com/blog/bull-usage#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F" class="hash-link" aria-label="生命周期的直接链接" title="生命周期的直接链接" translate="no">​</a></h4>
<p>为了充分利用 Bull 队列的全部潜力，了解任务的生命周期非常重要。从生产者在队列实例上调用<code>add</code>方法的那一刻起，任务进入一个生命周期，该生命周期将处于不同的状态，直到完成或失败（尽管从技术上讲，失败的任务可以重试并获得新的生命周期）。</p>
<p><img decoding="async" loading="lazy" src="https://optimalbits.github.io/bull/job-lifecycle.png" alt="Diagram showing job statuses" class="img_SPwZ"></p>
<p>当任务添加到队列中时，它可处于<strong>等待状态</strong>或<strong>延迟状态</strong>。等待状态其实是一个等待列表，所有列队在处理之前均处于等待状态，延迟状态意味着任务正在等待某些超时或处理失败的任务，延迟任务不会直接处理，而是在工作区间处于空闲状态时，将其放置在等待列表的开头并进行处理。</p>
<p>任务的下一个状态为"活动"状态。活动状态由一Redis的<code>set</code>集表示，是当前正在处理的任务，这时它们在<code>process</code>函数中运行。任务可以无限时间的处于处于活动状态，直到过程完成或引发异常，以便任务以"已完成"或"失败"状态结束。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="停滞任务">停滞任务<a href="https://3rcd.com/blog/bull-usage#%E5%81%9C%E6%BB%9E%E4%BB%BB%E5%8A%A1" class="hash-link" aria-label="停滞任务的直接链接" title="停滞任务的直接链接" translate="no">​</a></h4>
<p>在 Bull中，我们定义了停滞任务的概念。停滞任务虽然正在处理的任务，但 Bull 怀疑流程功能已挂起。当<code>process</code>函数正在处理的任务使 CPU 负载过大时，会导致工作区间无法告诉队列它仍在处理该任务，这时会造成停滞任务。</p>
<p>当任务停滞时，根据任务的设置，任务可由其他空闲工作区间重试，也可以切换到失败状态。</p>
<p>停滞任务可以通过确保进程函数不会使 Node 事件循环运行时间太长，或使用单独的<a href="https://3rcd.com/blog/bull-usage#%E7%8B%AC%E7%AB%8B%E8%BF%9B%E7%A8%8B" class="">沙盒处理器</a>来避免。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="事件">事件<a href="https://3rcd.com/blog/bull-usage#%E4%BA%8B%E4%BB%B6" class="hash-link" aria-label="事件的直接链接" title="事件的直接链接" translate="no">​</a></h3>
<p>Bull 中的队列拥有几个事件，这些事件在许多用例中很有用。事件可以是一个列队实例(一个工作区间)的本地事件，例如，如果一个任务在给定工作区间内完成，则将只为该实例发出本地事件。但是，可以监听所有事件，例如在本地事件名称前加上<code>global:</code>前缀。然后，我们可以监听指定队列的所有工作区间生成的所有事件。</p>
<p>一个本地的<code>completed</code>事件:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'completed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token parameter">job</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Job with id </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">job</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">id</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> has been completed</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<p>而下面这样就可以通过全局来监听:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'global:completed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token parameter">jobId</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Job with id </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">jobId</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> has been completed</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<p>请注意，全局事件的签名与本地事件的签名略有不同，在上面的示例中，它只发送任务的 ID 而不是任务本身的完整实例，这样做是出于性能原因。</p>
<p>可用事件的列表可在[reference文档] (<a href="https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#eventsk)%E4%B8%AD%E6%89%BE%E5%88%B0%E3%80%82" target="_blank" rel="noopener noreferrer" class="">https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#eventsk)中找到。</a></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="列队选项">列队选项<a href="https://3rcd.com/blog/bull-usage#%E5%88%97%E9%98%9F%E9%80%89%E9%A1%B9" class="hash-link" aria-label="列队选项的直接链接" title="列队选项的直接链接" translate="no">​</a></h3>
<p>队列可以在实例化时可以传入一些选项，例如，您可以指定 Redis 服务器的地址和密码，以及其他一些有用的设置。所有这些设置都在 Bull 的<a href="https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue" target="_blank" rel="noopener noreferrer" class="">reference文档</a>中找到，下面我们看一下一些选项的用例</p>
<blockquote>
<p>更多详细的API请参考<a href="https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue" target="_blank" rel="noopener noreferrer" class="">文档</a></p>
</blockquote>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="速率限制">速率限制<a href="https://3rcd.com/blog/bull-usage#%E9%80%9F%E7%8E%87%E9%99%90%E5%88%B6" class="hash-link" aria-label="速率限制的直接链接" title="速率限制的直接链接" translate="no">​</a></h4>
<p>为创建的队列限制在时间单位中处理的任务数。限制是每个队列定义的，与工作区间数量不一，因此您可以水平缩放，并且仍然能够轻松限制处理速率限制：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Limit queue to max 1.000 jobs per 5 seconds.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myRateLimitedQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'rateLimited'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">limiter</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">max</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">duration</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>当队列达到速率限制时，请求的任务将加入<code>delayed</code>队列。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="命名任务">命名任务<a href="https://3rcd.com/blog/bull-usage#%E5%91%BD%E5%90%8D%E4%BB%BB%E5%8A%A1" class="hash-link" aria-label="命名任务的直接链接" title="命名任务的直接链接" translate="no">​</a></h4>
<p>可以给任务命名不会改变队列的任何机制，但可获得更清晰的代码以及在UI 工具中的更好可视化：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Jobs producer</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'image'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">input</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'myimagefile'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'audio'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">input</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'myaudiofile'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">input</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'myvideofile'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Worker</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'image'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> processImage</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'audio'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> processAudio</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">transcoderQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> processVideo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>请记住，每个队列实例都需要为每个命名任务提供<em>一个</em>处理器，否则将抛出异常。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="沙盒处理器">沙盒处理器<a href="https://3rcd.com/blog/bull-usage#%E6%B2%99%E7%9B%92%E5%A4%84%E7%90%86%E5%99%A8" class="hash-link" aria-label="沙盒处理器的直接链接" title="沙盒处理器的直接链接" translate="no">​</a></h4>
<p>如上所述，在定义<code>process</code>函数时，还可以提供并发设置。此设置允许工作人员并行处理多个任务。任务仍在同一Node进程中处理，就算处理的OI密集非常高的任务也会处理正常。</p>
<p>但是有时需要处理CPU密集非常高的任务，这可能会锁定Node事件循环太久而导致Bull 可能会停止任务。为了避免这种情况，可以在单独的Node进程中的运行<code>process</code>函数。在这种情况下，并发参数将决定允许运行的并发进程的最大数量。</p>
<p>我们称这种进程为"沙盒"进程，这样就算某个进程崩溃也不会影响任何其他进程，并且将自动生成一个新进程来取代它。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="任务类型">任务类型<a href="https://3rcd.com/blog/bull-usage#%E4%BB%BB%E5%8A%A1%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="任务类型的直接链接" title="任务类型的直接链接" translate="no">​</a></h3>
<p>Bull 中的默认任务类型是"FIFO"（先出），这意味着任务的处理顺序与进入队列的顺序相同。按不同顺序处理任务时这很有用。</p>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="lifo">LIFO<a href="https://3rcd.com/blog/bull-usage#lifo" class="hash-link" aria-label="LIFO的直接链接" title="LIFO的直接链接" translate="no">​</a></h4>
<p>Lifo（最后一个先出）表示任务被添加到队列的开头，因此将在工作区间空闲时进行处理。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> myqueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">lifo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="延迟">延迟<a href="https://3rcd.com/blog/bull-usage#%E5%BB%B6%E8%BF%9F" class="hash-link" aria-label="延迟的直接链接" title="延迟的直接链接" translate="no">​</a></h4>
<p>使任务在处理之前延迟一定时间。请注意，延迟参数表示任务在进行处理之前等待的最短时间量。延迟时间过时，任务将移动到列队的开头，并在工作区间空闲时进行处理。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Delayed 5 seconds</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> myqueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">delay</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5000</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="优先级">优先级<a href="https://3rcd.com/blog/bull-usage#%E4%BC%98%E5%85%88%E7%BA%A7" class="hash-link" aria-label="优先级的直接链接" title="优先级的直接链接" translate="no">​</a></h4>
<p>任务可以设置优先级。优先级较高的任务将在优先级较低的任务之前进行处理。最高优先级为 1，数值越大优先级月底。请记住，优先级队列比标准队列慢一点（因为优先级列队的当前插入时间 O(n)的会替代标准队列的O(1))。</p>
<blockquote>
<p>上面括号中的n 代表当前在队列中等待的任务数</p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> myqueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">priority</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="重复">重复<a href="https://3rcd.com/blog/bull-usage#%E9%87%8D%E5%A4%8D" class="hash-link" aria-label="重复的直接链接" title="重复的直接链接" translate="no">​</a></h4>
<p>可重复任务是特殊任务，根据 cron 规范或时间间隔，可以无限期地重复，直到给定的最大时间或到达重复次数才停止(如果设置这两者的话)。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Repeat every 10 seconds for 100 times.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> myJob </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> myqueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">repeat</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">every</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">limit</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Repeat payment job once every day at 3:15 (am)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">paymentsQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">paymentsData</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">repeat</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">cron</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'15 3 * * *'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>关于可重复任务，有一些重要的注意事项：</p>
<ul>
<li class="">如果重复选项相同，Bull 不会添加相同的可重复任务。（注意：任务 ID 是重复选项的一部分，因为：<a href="https://github.com/OptimalBits/bull/pull/603%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%BC%A0%E9%80%92%E4%BB%BB%E5%8A%A1" target="_blank" rel="noopener noreferrer" class="">https://github.com/OptimalBits/bull/pull/603，因此传递任务</a> ID 将允许在队列中插入具有相同 cron 的任务）</li>
<li class="">如果没有正在运行的工作区间，则下次工作区间在线时，可重复任务将不累积。</li>
<li class="">可重复任务可以通过 <a href="https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueremoverepeatable" target="_blank" rel="noopener noreferrer" class="">removeRepeatable</a>方法删除</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="如何使用">如何使用<a href="https://3rcd.com/blog/bull-usage#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="如何使用的直接链接" title="如何使用的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基本使用">基本使用<a href="https://3rcd.com/blog/bull-usage#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="基本使用的直接链接" title="基本使用的直接链接" translate="no">​</a></h3>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token maybe-class-name">Queue</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'bull'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> videoQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video transcoding'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'redis://127.0.0.1:6379'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> audioQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'audio transcoding'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">redis</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">port</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">host</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'127.0.0.1'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">password</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foobared'</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Specify Redis connection using object</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> imageQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'image transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> pdfQueue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'pdf transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">videoQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// job.data contains the custom data passed when the job was created</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// job.id contains id of this job.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// transcode video asynchronously and report progress</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">progress</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// call done when finished</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or give a error if error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'error transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or pass it a result</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">framerate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">29.5</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* etc... */</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// If the job throws an unhandled exception it is also handled correctly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'some unexpected error'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">audioQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// transcode audio asynchronously and report progress</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">progress</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// call done when finished</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or give a error if error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'error transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or pass it a result</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">samplerate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">48000</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* etc... */</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// If the job throws an unhandled exception it is also handled correctly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'some unexpected error'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">imageQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// transcode image asynchronously and report progress</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">progress</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// call done when finished</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or give a error if error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'error transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// or pass it a result</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">width</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1280</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">height</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">720</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* etc... */</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// If the job throws an unhandled exception it is also handled correctly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'some unexpected error'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pdfQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Processors can also return promises instead of using the done callback</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">pdfAsyncProcessor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">videoQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">video</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'http://example.com/video1.mov'</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">audioQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">audio</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'http://example.com/audio1.mp3'</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">imageQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">image</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'http://example.com/image1.tiff'</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用promises">使用promises<a href="https://3rcd.com/blog/bull-usage#%E4%BD%BF%E7%94%A8promises" class="hash-link" aria-label="使用promises的直接链接" title="使用promises的直接链接" translate="no">​</a></h3>
<p>你可以返回 promises来替代 <code>done</code> 回调函数:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">videoQueue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// don't forget to remove the done callback!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Simply return a promise</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetchVideo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">transcodeVideo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Handles promise rejection</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">reject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'error transcoding'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Passes the value the promise is resolved with to the "completed" event</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">framerate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">29.5</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* etc... */</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// If the job throws an unhandled exception it is also handled correctly</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'some unexpected error'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// same as</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">reject</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'some unexpected error'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="独立进程">独立进程<a href="https://3rcd.com/blog/bull-usage#%E7%8B%AC%E7%AB%8B%E8%BF%9B%E7%A8%8B" class="hash-link" aria-label="独立进程的直接链接" title="独立进程的直接链接" translate="no">​</a></h3>
<p><code>process</code>函数可以运行在独立进程中 . 这样做有一下几个优点:</p>
<ul>
<li class="">进程是一个沙盒，所以就算崩溃也不会影响其它程序工作。</li>
<li class="">你可以在不影响列队的情况下运行阻塞代码 （任务不会停滞）。</li>
<li class="">多核CPU的利用率要好得多。</li>
<li class="">与Redis的连接更少。</li>
</ul>
<p>要运行此功能只需要创建单独的文件：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// processor.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method-variable function-variable method function property-access" style="color:#d73a49">exports</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Do some heavy work</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>并定义处理器，像这样：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Single process:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'/path/to/my/processor.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// You can use concurrency as well:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/path/to/my/processor.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// and named processors:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'my processor'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/path/to/my/processor.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="重复任务">重复任务<a href="https://3rcd.com/blog/bull-usage#%E9%87%8D%E5%A4%8D%E4%BB%BB%E5%8A%A1" class="hash-link" aria-label="重复任务的直接链接" title="重复任务的直接链接" translate="no">​</a></h3>
<p>任务可以添加到队列中，并根据 cron 规范重复处理：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">  paymentsQueue.process(function(job){</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    // Check payments</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  });</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  // Repeat payment job once every day at 3:15 (am)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  paymentsQueue.add(paymentsData, {repeat: {cron: '15 3 * * *'}});</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div></div></div>
<p>在<a href="https://crontab.cronhub.io/" target="_blank" rel="noopener noreferrer" class="">此处</a>检查表达式以验证它们是否正确</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="暂停--恢复">暂停 / 恢复<a href="https://3rcd.com/blog/bull-usage#%E6%9A%82%E5%81%9C--%E6%81%A2%E5%A4%8D" class="hash-link" aria-label="暂停 / 恢复的直接链接" title="暂停 / 恢复的直接链接" translate="no">​</a></h3>
<p>A queue can be paused and resumed globally (pass <code>true</code> to pause processing for
just this worker):</p>
<p>可以全局暂停和恢复队列（通过此工作区间的暂停处理）：<code>true</code></p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// queue is paused now</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resume</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// queue is resumed now</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="事件-1">事件<a href="https://3rcd.com/blog/bull-usage#%E4%BA%8B%E4%BB%B6-1" class="hash-link" aria-label="事件的直接链接" title="事件的直接链接" translate="no">​</a></h3>
<p>队列会触发一些有用的事件，例如...</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'completed'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Job completed with output result!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div></div></div>
<p>有关事件（包括已触发事件的完整列表）的信息，请查看<a href="https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#events" target="_blank" rel="noopener noreferrer" class="">事件参考</a></p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="队列性能">队列性能<a href="https://3rcd.com/blog/bull-usage#%E9%98%9F%E5%88%97%E6%80%A7%E8%83%BD" class="hash-link" aria-label="队列性能的直接链接" title="队列性能的直接链接" translate="no">​</a></h3>
<p>队列很便宜，因此如果您需要其中的许多队列，只需创建具有不同名称的新队列：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-javascript codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-javascript codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> userJohn </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'john'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> userLisa </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'lisa'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">.</span><br></span></code></pre></div></div></div></div>
<p>但是，每个队列实例都需要新的Redis连接，查看<a href="https://github.com/OptimalBits/bull/blob/master/PATTERNS.md#reusing-redis-connections" target="_blank" rel="noopener noreferrer" class="">如何重用连接</a>，或者您也可以使用<a href="https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueprocess" target="_blank" rel="noopener noreferrer" class="">命名任务</a>来实现类似的结果。</p>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="群集支持"><del>群集支持</del><a href="https://3rcd.com/blog/bull-usage#%E7%BE%A4%E9%9B%86%E6%94%AF%E6%8C%81" class="hash-link" aria-label="群集支持的直接链接" title="群集支持的直接链接" translate="no">​</a></h3>
<blockquote>
<p>从版本 3.2.0 及以上版本，建议使用线程处理器。</p>
</blockquote>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token maybe-class-name">Queue</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'bull'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  cluster </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'cluster'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> numWorkers </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> queue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Queue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"test concurrent queue"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cluster</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">isMaster</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> numWorkers</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    cluster</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fork</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  cluster</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'online'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">worker</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Lets create a few jobs for the queue workers</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token number" style="color:#36acaa">500</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">foo</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  cluster</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'exit'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">worker</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> code</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> signal</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'worker '</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> worker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pid</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">' died'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  queue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">process</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">job</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> jobDone</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Job done by worker"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cluster</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">worker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">jobDone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="官方文档">官方文档<a href="https://3rcd.com/blog/bull-usage#%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3" class="hash-link" aria-label="官方文档的直接链接" title="官方文档的直接链接" translate="no">​</a></h2>
<p>有关完整文档，请查看官方wiki</p>]]></content:encoded>
            <category>bull</category>
            <category>queue</category>
            <category>mq</category>
            <category>bullmq</category>
            <category>typescript</category>
            <category>nestjs</category>
        </item>
        <item>
            <title><![CDATA[accesscontrol使用指南]]></title>
            <link>https://3rcd.com/blog/accesscontrol-usage</link>
            <guid>https://3rcd.com/blog/accesscontrol-usage</guid>
            <pubDate>Sun, 19 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[基于角色和属性的Node.js访问控制]]></description>
            <content:encoded><![CDATA[<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基于角色和属性的nodejs访问控制">基于角色和属性的Node.js访问控制<a href="https://3rcd.com/blog/accesscontrol-usage#%E5%9F%BA%E4%BA%8E%E8%A7%92%E8%89%B2%E5%92%8C%E5%B1%9E%E6%80%A7%E7%9A%84nodejs%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6" class="hash-link" aria-label="基于角色和属性的Node.js访问控制的直接链接" title="基于角色和属性的Node.js访问控制的直接链接" translate="no">​</a></h3>
<p>虽然许多[RBAC][rbac]（基于角色的访问控制）实现上有所不同，但基础知识都是一样的，这种模式也被广泛采用，因为它模拟了真实生活角色(任务)分配。 但是数据变得越来越复杂; 您需要在资源，功能甚至环境中定义策略。 这称为 [ABAC][abac] （基于属性的访问控制）。</p>
<p>我们需要合并以上两者的最佳特性（见[NIST paper][nist-paper]）; 这个node库不仅实现了RBAC基础知识，并且还关注* resource <em>和</em> action *属性。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="核心功能">核心功能<a href="https://3rcd.com/blog/accesscontrol-usage#%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD" class="hash-link" aria-label="核心功能的直接链接" title="核心功能的直接链接" translate="no">​</a></h2>
<ul>
<li class="">链式的，友好的API。
例如<code>ac.can(role).create(resource)</code></li>
<li class="">角色分层<strong>继承</strong>。</li>
<li class="">可<strong>一次</strong>定义授权（例如从数据库结果）也可以<strong>逐个</strong>定义授权。</li>
<li class="">通过<strong>glob表示法</strong>定义的属性授予/拒绝权限（支持嵌套对象）。</li>
<li class="">能够设置可允许的属性<strong>过滤</strong>数据（模型）实例。</li>
<li class="">能够控制<strong>自己创建</strong>的或<strong>任何</strong>资源的访问。</li>
<li class="">能够<strong>锁定</strong>基础授权模型。</li>
<li class="">没有<strong>静默</strong>错误。</li>
<li class=""><strong>快</strong>。（授权存储在内存中，没有数据库查询。）</li>
<li class=""><strong>经过</strong>严格<strong>测试</strong>。</li>
<li class="">TypeScript支持。</li>
</ul>
<p><em>为了构建更加健壮的应用，这个库（v1.5.0 +）完全用TypeScript重写</em></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="安装">安装<a href="https://3rcd.com/blog/accesscontrol-usage#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h2>
<p>使用 <a href="https://www.npmjs.com/package/accesscontrol" target="_blank" rel="noopener noreferrer" class=""><strong>npm</strong></a>: <code>npm i accesscontrol --save</code><br>
<!-- -->使用 <a href="https://yarn.pm/accesscontrol" target="_blank" rel="noopener noreferrer" class=""><strong>yarn</strong></a>: <code>yarn add accesscontrol</code></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="使用指南">使用指南<a href="https://3rcd.com/blog/accesscontrol-usage#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97" class="hash-link" aria-label="使用指南的直接链接" title="使用指南的直接链接" translate="no">​</a></h2>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token maybe-class-name">AccessControl</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'accesscontrol'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// or:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// import { AccessControl } from 'accesscontrol';</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="基础示例">基础示例<a href="https://3rcd.com/blog/accesscontrol-usage#%E5%9F%BA%E7%A1%80%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="基础示例的直接链接" title="基础示例的直接链接" translate="no">​</a></h3>
<p>逐个定义 roles（权限） 和grants（角色）</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ac </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">AccessControl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">                    </span><span class="token comment" style="color:#999988;font-style:italic">// 定义新角色或修改现有角色。也可以是一个数组。</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">             </span><span class="token comment" style="color:#999988;font-style:italic">// 与.createOwn('video', ['*'])相同 ['*']为默认参数</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">deleteOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">                   </span><span class="token comment" style="color:#999988;font-style:italic">// 切换到另一个角色而不破坏操作链</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">                 </span><span class="token comment" style="color:#999988;font-style:italic">// 继承角色功能。一样，也可以是一个数组 </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">updateAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'title'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 明确定义可操作的属性 </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">deleteAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> permission </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">can</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">granted</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// —&gt; true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">attributes</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// —&gt; ['*'] (所有属性)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">permission </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">can</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">updateAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">granted</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// —&gt; true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">attributes</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// —&gt; ['title']</span><br></span></code></pre></div></div></div></div>
<h3 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="expressjs示例">Express.js示例<a href="https://3rcd.com/blog/accesscontrol-usage#expressjs%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="Express.js示例的直接链接" title="Express.js示例的直接链接" translate="no">​</a></h3>
<p>检查所请求资源和操作的角色权限，如果已授权则返回权限筛选出的属性进行响应</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ac </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">AccessControl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">grants</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">router</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'/videos/:title'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">req</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> res</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> next</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> permission </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">can</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">granted</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token maybe-class-name">Video</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">find</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">params</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">title</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">err</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">end</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token comment" style="color:#999988;font-style:italic">// filter data by permission attributes and send.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// resource is forbidden for this user/role</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">403</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">end</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="角色">角色<a href="https://3rcd.com/blog/accesscontrol-usage#%E8%A7%92%E8%89%B2" class="hash-link" aria-label="角色的直接链接" title="角色的直接链接" translate="no">​</a></h2>
<p>您可以通过轻松地调用<code>AccessControl</code>实例上的方法<code>.grant(&lt;role&gt;)</code>或<code>.deny(&lt;role&gt;)</code>方法来创建/定义角色。</p>
<ul>
<li class="">角色也可以继承自其它角色.</li>
</ul>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 用户角色继承查看者角色权限</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'viewer'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 管理员角色继承普通用户和编辑员的角色权限</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'editor'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 管理员和超级管理员角色都继承了版主权限</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'superadmin'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'moderator'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<ul>
<li class="">继承是通过引用完成的，因此您可以在继承角色之前或之后授予资源权限。</li>
</ul>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 案例 #1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 假设用户角色已经存在 </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 案例 #2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 以下结果对于两种情况都是相同的</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> permission </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">can</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">granted</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// true</span><br></span></code></pre></div></div></div></div>
<p>继承说明：</p>
<ul>
<li class="">角色不能自我继承。</li>
<li class="">不允许交叉继承。
例如<code>ac.grant('user').extend('admin').grant('admin').extend('user')</code>将抛出异常。</li>
<li class="">角色不能（预）继承不存在的角色。换句话说，您应该首先创建基本角色。例如<code>ac.grant('baseRole').grant('role').extend('baseRole')</code></li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="动作和动作属性">动作和动作属性<a href="https://3rcd.com/blog/accesscontrol-usage#%E5%8A%A8%E4%BD%9C%E5%92%8C%E5%8A%A8%E4%BD%9C%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="动作和动作属性的直接链接" title="动作和动作属性的直接链接" translate="no">​</a></h2>
<p><a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank" rel="noopener noreferrer" class="">CRUD</a>操作是您可以对资源执行的操作。有两个动作属性定义了资源的<strong>所有权</strong>：<em>own</em>和<em>any</em>。</p>
<p>例如，一个<code>admin</code>角色可以<code>create</code>，<code>read</code>，<code>update</code>或<code>delete</code>（CRUD）<strong>任何</strong> <code>account</code>资源。但是，一个<code>user</code>角色可能只<code>read</code>或<code>update</code>它<strong>自己的</strong> <code>account</code>资源。</p>
<table><thead><tr><th>操作</th><th>所有权</th></tr></thead><tbody><tr><td rowspan="2"><p><b>C</b>reate<br>
<b>R</b>ead<br>
<b>U</b>pdate<br>
<b>D</b>elete<br></p></td><td>自己的资源</td><td>可以(或不可以)对当前请求的自己的资源执行C|R|U|D 操作。</td></tr><tr><td>任何资源</td><td>可以(或不可以)对任何资源执行C|R|U|D 操作,包括自己的资源。</td></tr></tbody></table>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'role'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'resource'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">deny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'role'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">deleteAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'resource'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p><em>请注意，操作<strong>自己的资源</strong>也要求您检查实际所有权。<a href="https://github.com/onury/accesscontrol/issues/14#issuecomment-328316670" target="_blank" rel="noopener noreferrer" class="">查看此处</a> 获取更多信息。</em></p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="资源和资源属性">资源和资源属性<a href="https://3rcd.com/blog/accesscontrol-usage#%E8%B5%84%E6%BA%90%E5%92%8C%E8%B5%84%E6%BA%90%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="资源和资源属性的直接链接" title="资源和资源属性的直接链接" translate="no">​</a></h2>
<p>多个角色可以访问特定资源。但是根据上下文，您可能需要限制特定角色可访问的资源内容。</p>
<p>这可以通过资源属性实现。您可以使用Glob表示法来定义允许或拒绝的资源属性。</p>
<p>例如，我们有一个<code>video</code>具有以下属性的资源：<code>id</code>，<code>title</code>和<code>runtime</code>。<code>admin</code>角色可以读取<em>任何</em> <code>video</code>资源的所有属性：</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 也可以这样写:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ac.grant('admin').readAny('video');</span><br></span></code></pre></div></div></div></div>
<p>但是<code>id</code>属性不应该被<code>user</code>角色读取。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!id'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 也可以这样写:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ac.grant('user').readOwn('video', ['title', 'runtime']);</span><br></span></code></pre></div></div></div></div>
<p>你也可以嵌套对象 (属性).</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'account'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!record.id'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="检查权限和过滤属性">检查权限和过滤属性<a href="https://3rcd.com/blog/accesscontrol-usage#%E6%A3%80%E6%9F%A5%E6%9D%83%E9%99%90%E5%92%8C%E8%BF%87%E6%BB%A4%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="检查权限和过滤属性的直接链接" title="检查权限和过滤属性的直接链接" translate="no">​</a></h2>
<p>你可以调用<code>AccessControl</code>实例的<code>.can(&lt;role&gt;).&lt;action&gt;(&lt;resource&gt;)</code>方法来检查对指定资源和行为的权限。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> permission </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">can</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'account'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">granted</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic">// true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">attributes</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ['*', '!record.id']</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">permission</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// filtered data (without record.id)</span><br></span></code></pre></div></div></div></div>
<p>见 express.js 示例.</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="一次定义所有授权">一次定义所有授权<a href="https://3rcd.com/blog/accesscontrol-usage#%E4%B8%80%E6%AC%A1%E5%AE%9A%E4%B9%89%E6%89%80%E6%9C%89%E6%8E%88%E6%9D%83" class="hash-link" aria-label="一次定义所有授权的直接链接" title="一次定义所有授权的直接链接" translate="no">​</a></h2>
<p>你可以一次把所有授权传递给 <code>AccessControl</code> 的构造方法.
它也可以接受一个对象 <code>Object</code>:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 这实际上是如何在内部维护授权的方案</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> grantsObject </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">admin</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">video</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'create:any'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!views'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'read:any'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'update:any'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!views'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'delete:any'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">user</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">video</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'create:own'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!rating'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!views'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'read:own'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'update:own'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!rating'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'!views'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-property property" style="color:#36acaa">'delete:own'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'*'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ac </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">AccessControl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">grantsObject</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>... 也可以传递一个 数组 (从数据库中获取时很有用):</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 从数据库获取的授权列表 (必须在内部转换为如下格式的有效的grants对象)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> grantList </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'create:any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*, !views'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'read:any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'update:any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*, !views'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'delete:any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'create:own'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*, !rating, !views'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'read:any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'update:own'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*, !rating, !views'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'user'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'delete:own'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">attributes</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'*'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ac </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">AccessControl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">grantList</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>你可以随时设置授权...</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> ac </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">AccessControl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setGrants</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">grantsObject</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getGrants</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<p>...除非你锁定它:</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-js codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-js codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">ac</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">lock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setGrants</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// throws after locked</span><br></span></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="适配nestjs">适配nest.js<a href="https://3rcd.com/blog/accesscontrol-usage#%E9%80%82%E9%85%8Dnestjs" class="hash-link" aria-label="适配nest.js的直接链接" title="适配nest.js的直接链接" translate="no">​</a></h2>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="一个基于onuryaccesscontrol实现的nestjs权限控制模块">一个基于<a href="https://github.com/onury/accesscontrol" target="_blank" rel="noopener noreferrer" class="">onury/accesscontrol</a>实现的Nestjs权限控制模块<a href="https://3rcd.com/blog/accesscontrol-usage#%E4%B8%80%E4%B8%AA%E5%9F%BA%E4%BA%8Eonuryaccesscontrol%E5%AE%9E%E7%8E%B0%E7%9A%84nestjs%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6%E6%A8%A1%E5%9D%97" class="hash-link" aria-label="一个基于onuryaccesscontrol实现的nestjs权限控制模块的直接链接" title="一个基于onuryaccesscontrol实现的nestjs权限控制模块的直接链接" translate="no">​</a></h4>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="本模块提供什么-">本模块提供什么 ?<a href="https://3rcd.com/blog/accesscontrol-usage#%E6%9C%AC%E6%A8%A1%E5%9D%97%E6%8F%90%E4%BE%9B%E4%BB%80%E4%B9%88-" class="hash-link" aria-label="本模块提供什么 ?的直接链接" title="本模块提供什么 ?的直接链接" translate="no">​</a></h4>
<p>在这个模块中，您将拥有开箱即用的以下所有功能（只用于Nest.js）。</p>
<ul>
<li class="">它是**基于装饰器的，**因为大多数时候你会在你的路由中使用装饰器。</li>
<li class="">内置<strong>ACGuard</strong>，您可以直接使用它。</li>
<li class="">从任何地方都可以访问底层的<strong>AccessControl</strong>对象。</li>
</ul>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="安装-1">安装<a href="https://3rcd.com/blog/accesscontrol-usage#%E5%AE%89%E8%A3%85-1" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h2>
<ul>
<li class="">NPM:</li>
</ul>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-bash codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-bash codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">npm install nest-access-control --save</span><br></span></code></pre></div></div></div></div>
<ul>
<li class="">Yarn:</li>
</ul>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-bash codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-bash codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">yarn add nest-access-control</span><br></span></code></pre></div></div></div></div>
<hr>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="示例">示例<a href="https://3rcd.com/blog/accesscontrol-usage#%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="示例的直接链接" title="示例的直接链接" translate="no">​</a></h4>
<blockquote>
<p>查看示例目录以获取更多代码;</p>
</blockquote>
<p>加入我们需要构建视频服务，以便用户可以与他人分享视频，但我们需要一些<code>admins</code>来控制这些视频。</p>
<ol>
<li class="">首先让我们定义角色:</li>
</ol>
<p>为了构建我们的角色，我们需要这个<code>RolesBuilder</code>类，它继承自<code>accesscontrol</code>包的<code>AccessControl</code>类。</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-ts codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-ts codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// app.roles.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">enum</span><span class="token plain"> AppRoles </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token constant" style="color:#36acaa">USER_CREATE_ANY_VIDEO</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'USER_CREATE_ANY_VIDEO'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token constant" style="color:#36acaa">ADMIN_UPDATE_OWN_VIDEO</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'ADMIN_UPDATE_OWN_VIDEO'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> roles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> RolesBuilder </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">RolesBuilder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">roles</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">AppRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">USER_CREATE_ANY_VIDEO</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// define new or modify existing role. also takes an array.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">createOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// equivalent to .createOwn('video', ['*'])</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">deleteOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">readAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">grant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">AppRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">ADMIN_UPDATE_OWN_VIDEO</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// switch to another role without breaking the chain</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">extend</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">AppRoles</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">USER_CREATE_ANY_VIDEO</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// inherit role capabilities. also takes an array</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">updateAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'title'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// explicitly defined attributes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">deleteAny</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div>
<blockquote>
<p>专家提示 ? ：请将所有角色组织在一个文件中，例如： <code>app.roles.ts</code>。</p>
</blockquote>
<ol start="2">
<li class="">接着让我们在跟模块中使用<code>AccessControlModule</code>注册角色：</li>
</ol>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-ts codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-ts codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// app.module.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> roles </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./app.roles'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">Module</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  imports</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">AccessControlModule</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">forRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">roles</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  controllers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">AppController</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  providers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">AppService</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AppModule</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>直到现在一切都很好，现在让我们构建我们的应用程序，假设我们有视频名称列表，用户可以 - <em>根据我们的角色</em> - <code>create:own</code>新视频或<code>read:any</code>视频，好的，让我们开始构建它</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-ts codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-ts codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// app.controller.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">Controller</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AppController</span><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> appService</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> AppService</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">UseGuards</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">AuthGuard</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ACGuard</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">UseRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		resource</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">'video'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">'read'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		possession</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">'any'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token function" style="color:#d73a49">root</span><span class="token punctuation" style="color:#393A34">(</span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">UserRoles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> userRoles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">appService</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">root</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userRoles</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></div></div>
<p>那么让我们讨论一下发生了什么！</p>
<p>首先我们介绍了两个新装饰器，实际上它们是三个，但让我们看看它们能做什么：</p>
<ul>
<li class=""><code>@UseRoles({ ... })</code>：这是最常用的装饰器，它定义用户允许访问此路由的角色。它可以设置一个或多个角色，但请记住，<strong>必须</strong>满足所有角色。角色的结构非常简单，例如，我们在这里定义了我们拥有的资源，以及<strong>ACGuard *</strong> - 将检查用户角色，然后如果用户角色具有访问此资源的权限，则守卫将返回<code>true</code>，否则将抛出一个<code>ForbiddenException</code>。关于角色的结构的更多信息请参阅<code>roles.interface.ts</code>文件或读取<code>accesscontrol</code>库的<a href="https://onury.io/accesscontrol/" target="_blank" rel="noopener noreferrer" class="">原始文档</a>。</li>
<li class=""><code>UserRoles(&lt;prop&gt;)</code>：如果你想直接访问用户角色，也许你就想手动检查它的角色，而不是让<code>ACGuard</code>为你做这些，然后你就会寻找<code>ACGuard</code>这个装饰器。这个装饰器它其实很简单，它只是获取<code>req.user.roles</code>从<code>request</code>对象返回值，但是等等，如果用户的角色中不存在<code>prop: role</code>，我们知道你会问这个问题，这样你就可以将一个可选的属性键传递给装饰器了以便从用户对象获取它，例如<code>@UserRoles('permissions')</code>将返回<code>req.user.permissions</code>。</li>
<li class=""><code>@InjectRolesBuilder()</code>: If you hate the <code>ACGuard</code> - <em>imo it's a good guard</em> - and want to build your own Guard instead, you will likely need to access to the underlying <code>RolesBuilder</code> Object , then that decorator for you, it will inject the <code>Roles</code> you have defined before, i.e the object passed to the <code>AccessControlModule.forRoles(roles)</code>.</li>
<li class=""><code>@InjectRolesBuilder()</code>：如果你不喜欢的<code>ACGuard</code>- <em>这是一个很好的守卫</em> -如果你想建立自己的守卫代替它，您可能需要访问底层<code>RolesBuilder</code>对象，那么这个装饰器将会注入你之前已定义的<code>Roles</code>，即传递给<code>AccessControlModule.forRoles(roles)</code>的对象。</li>
</ul>
<h4 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="限制">限制<a href="https://3rcd.com/blog/accesscontrol-usage#%E9%99%90%E5%88%B6" class="hash-link" aria-label="限制的直接链接" title="限制的直接链接" translate="no">​</a></h4>
<p>首先，这个模块假设以下情况</p>
<ol>
<li class="">在 <code>req.user</code>存在用户对象</li>
<li class="">您可以自己构建<code>AuthGuard</code>将<code>user</code>对象附加到<code>req</code>对象的内容,<a href="https://docs.nestjs.com/guards" target="_blank" rel="noopener noreferrer" class="">查看详细方法</a></li>
<li class="">the <code>AuthGuard</code> must be registered before roles guard, in this case it's <code>ACGuard</code>, and of course you can combine the <code>AuthGuard</code> and <code>ACGuard</code> in one guard, and use it everywhere.</li>
<li class=""><code>AuthGuard</code>必须在roles守卫之前注册，在这个案例中roles守卫就是<code>ACGuard</code>，当然你可以把<code>AuthGuard</code>和<code>ACGuard</code>放在一个守卫中，并在任何地方使用它。</li>
</ol>
<p>其次，我不认为这些是限制，因为你可以轻松地建立自己的守卫，而不再需要内置的了。</p>]]></content:encoded>
            <category>accesscontrol</category>
            <category>typescript</category>
            <category>nestjs</category>
        </item>
        <item>
            <title><![CDATA[Mysql远程连接]]></title>
            <link>https://3rcd.com/blog/mysql-remote-access</link>
            <guid>https://3rcd.com/blog/mysql-remote-access</guid>
            <pubDate>Thu, 16 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[有两台云服务器,一台性能和内存很好,另一台带宽够大,所以内存大的放数据库,带宽大的做web服务器,这需要配置一下Mysql的远程访问]]></description>
            <content:encoded><![CDATA[<p>有两台云服务器,一台性能和内存很好,另一台带宽够大,所以内存大的放数据库,带宽大的做web服务器,这需要配置一下Mysql的远程访问</p>
<p>登录mysql并更新表就你可以</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">mysql -u root -p </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CREATE USER 'root'@'%' IDENTIFIED BY '密码';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">FLUSH PRIVILEGES;</span><br></span></code></pre></div></div></div></div>]]></content:encoded>
            <category>mysql</category>
            <category>mariadb</category>
            <category>linux</category>
        </item>
        <item>
            <title><![CDATA[mysql8更改密码注意事项]]></title>
            <link>https://3rcd.com/blog/mysql8-change-password</link>
            <guid>https://3rcd.com/blog/mysql8-change-password</guid>
            <pubDate>Thu, 09 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[安装后]]></description>
            <content:encoded><![CDATA[<p>安装后
<code>ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';</code></p>
<p>如果报错，那是因为你在安装的时候设置了密码复杂度，清除设置就可以</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">set global validate_password.policy=0;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">set global validate_password.length=4;</span><br></span></code></pre></div></div></div></div>
<p>然后退出后再执行</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-text codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-text codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">mysql_secure_installation</span><br></span></code></pre></div></div></div></div>
<p>再执行上面的<code>ALTER</code>命令就可以了</p>]]></content:encoded>
            <category>mysql</category>
            <category>msyql8</category>
            <category>linux</category>
        </item>
        <item>
            <title><![CDATA[Mysql假死现象]]></title>
            <link>https://3rcd.com/blog/mysql-error</link>
            <guid>https://3rcd.com/blog/mysql-error</guid>
            <pubDate>Wed, 08 Jun 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Windows is windows.]]></description>
            <content:encoded><![CDATA[<div class="theme-tabs-container tabs-container tabList_rDS5"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_B01N tabs__item--active">Windows</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_B01N">Unix</li></ul><div role="tabpanel" class="tabItem_Nm2r margin-top--md">Windows is windows.</div></div>
<div class="theme-admonition theme-admonition-tip admonition_M1T2 alert alert--success"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_ndgZ"><div class="impression"> 其实很多问题只需要耐心的谷歌基本都可以解决 </div></div></div>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="起因">起因<a href="https://3rcd.com/blog/mysql-error#%E8%B5%B7%E5%9B%A0" class="hash-link" aria-label="起因的直接链接" title="起因的直接链接" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-note admonition_M1T2 alert alert--secondary"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>备注</div><div class="admonitionContent_ndgZ"><p>Some <strong>content</strong> with <em>markdown</em> <code>syntax</code>. Check <a href="https://3rcd.com/blog/mysql-error#" class="">this <code>api</code></a>.</p></div></div>
<div class="theme-admonition theme-admonition-tip admonition_M1T2 alert alert--success"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_ndgZ"><p>Some <strong>content</strong> with <em>markdown</em> <code>syntax</code>. Check <a href="https://3rcd.com/blog/mysql-error#" class="">this <code>api</code></a>.</p></div></div>
<div class="theme-admonition theme-admonition-info admonition_M1T2 alert alert--info"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_ndgZ"><p>Some <strong>content</strong> with <em>markdown</em> <code>syntax</code>. Check <a href="https://3rcd.com/blog/mysql-error#" class="">this <code>api</code></a>.</p></div></div>
<div class="theme-admonition theme-admonition-caution admonition_M1T2 alert alert--warning"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>警告</div><div class="admonitionContent_ndgZ"><p>Some <strong>content</strong> with <em>markdown</em> <code>syntax</code>. Check <a href="https://3rcd.com/blog/mysql-error#" class="">this <code>api</code></a>.</p></div></div>
<div class="theme-admonition theme-admonition-danger admonition_M1T2 alert alert--danger"><div class="admonitionHeading_Bx4J"><span class="admonitionIcon_dWSv"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>危险</div><div class="admonitionContent_ndgZ"><p>Some <strong>content</strong> with <em>markdown</em> <code>syntax</code>. Check <a href="https://3rcd.com/blog/mysql-error#" class="">this <code>api</code></a>.</p></div></div>
<p>最近发现使用PHP架设的几个站点和应用一直出现打不开假死的现象，而使用同一台服务器的静态应用完全OK。重启过后一切正常，过段时间又是这样。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="过程">过程<a href="https://3rcd.com/blog/mysql-error#%E8%BF%87%E7%A8%8B" class="hash-link" aria-label="过程的直接链接" title="过程的直接链接" translate="no">​</a></h2>
<p>静态站点能打开就证明应该不是nginx的问题，在加上服务器上运行着内存老虎-nextcloud，所以理所当然的以为问题出在php-fpm上。因为服务器架设的是多版本的php(php7.4和php8.1)，但是php8的站点还是能打开，只不过有点卡，而php7的则直接卡死，这又让我走了一下弯路，以为问题是出在php-fpm74身上，然后自然而然的调整php7的php.ini，php-fpm.conf里面的参数，并在 <code>service php74-fpm restart</code> 之后问题依旧。</p>
<p>接着打开php74-fpm的日志进行查看，并没发现异常。这时候nginx和php-fpm的问题基本已经排除了，因为是wordpress站点，所以并没有Redis，RabbitMQ这些其余中间件的问题，所以瞬间意识到问题一定是出现在了Mysql身上。</p>
<p>尝试<code>service restart mysqld</code>，发现没有反应，卡在那边，这是庆幸问题终于找到了。但是该怎么处理呢？第一步当然是查看日志，因为服务器用的是Mariadb，并且为了利用外挂磁盘，所以数据目录放在挂载额外磁盘的<code>/data</code>目录，cat一下<code>/data/mariadb/mysql-error.log</code>，真的找到了错误，出现了这么一条日志</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">[ERROR] mariadbd: Error writing file 'mysql-bin' (errno: 28 "No space left on device")</span><br></span></code></pre></div></div></div></div>
<p>开始利用宇宙第一神器<a href="https://google.com/" target="_blank" rel="noopener noreferrer" class="">google.com</a>进行搜索，发现在<a href="https://stackoverflow.com/" target="_blank" rel="noopener noreferrer" class="">stackoverflow</a>上遇到此类问题的人还挺多，其中一个回答说的是数据目录挂载的磁盘容量被占满，一句话被点醒。</p>
<p>使用<code>df -h</code>命令查看磁盘占用，如下图，其</p>
<p><img decoding="async" loading="lazy" src="https://3rcd.com/assets/images/mysql-error-42684449c00957db12a8855cdc7cbdca.png" width="701" height="230" class="img_SPwZ"></p>
<p>打开<code>/data</code>目录，使用<code>du -sh *</code>命令查看文件的占用，发现了满屏以<code>mysql-bin.</code>开头的文件，并且每个文件占用大概1G多，这些文件一般来说是用来进行主从复制时使用的，然后我一单服务器给我生成这么一大堆，磁盘怎么可能不被沾满。。。</p>
<h2 class="anchor anchorTargetHideOnScrollNavbar_wE9v" id="解决">解决<a href="https://3rcd.com/blog/mysql-error#%E8%A7%A3%E5%86%B3" class="hash-link" aria-label="解决的直接链接" title="解决的直接链接" translate="no">​</a></h2>
<p>解决方法很简单，只要<code>rm -rf  mysql-bin.*</code>清空这些文件，然后编辑<code>/etc/my.cnf</code>，注释掉以下两项，关闭自动生成就行</p>
<div class="browserWindow_yd7a"><div class="browserWindowHeader_LDkY"><div class="buttons_rXmM"><span class="dot_LeAN" style="background:#f25f58"></span><span class="dot_LeAN" style="background:#fbbe3c"></span><span class="dot_LeAN" style="background:#58cb42"></span></div></div><div class="browserWindowBody_S7B5" style="overflow:auto;padding:0;min-height:3rem;max-height:25rem;height:auto"><div class="language-shell codeBlockContainer_OWV6 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Jp64"><pre tabindex="0" class="prism-code language-shell codeBlock_vA6v thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_nPsZ"><span class="token-line" style="color:#393A34"><span class="token plain">#log_bin = mysql-bin</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#binlog_format = mixed</span><br></span></code></pre></div></div></div></div>
<p>最后重启Mysql/Mariadb就行，现在试试<code>service mysqld restart</code>，不再卡主，站点也能正常运行</p>]]></content:encoded>
            <category>mysql</category>
            <category>mariadb</category>
            <category>linux</category>
        </item>
    </channel>
</rss>