<?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>Meng Blog</title>
        <link>https://blog.mengfei.tech/blog</link>
        <description>Meng Blog</description>
        <lastBuildDate>Mon, 19 Oct 2026 10:36:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[AGENTS]]></title>
            <link>https://blog.mengfei.tech/blog/AGENTS</link>
            <guid>https://blog.mengfei.tech/blog/AGENTS</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Docusaurus 博客内容根目录。文章为 Markdown，按主题分子目录发布。]]></description>
            <content:encoded><![CDATA[<p>Docusaurus 博客内容根目录。文章为 Markdown，按主题分子目录发布。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="current-layout">Current Layout<a href="https://blog.mengfei.tech/blog/AGENTS#current-layout" class="hash-link" aria-label="Direct link to Current Layout" title="Direct link to Current Layout" translate="no">​</a></h2>
<table><thead><tr><th>目录</th><th>说明</th></tr></thead><tbody><tr><td><code>Nodejs/</code></td><td>Node/npm 相关</td></tr><tr><td><code>React/</code></td><td>React 相关</td></tr><tr><td><code>Ts/</code></td><td>TypeScript 相关</td></tr><tr><td><code>Docker/</code></td><td>Docker 命令与用法</td></tr><tr><td><code>Linux/</code></td><td>Linux 环境</td></tr><tr><td><code>Windows/</code></td><td>Windows/PowerShell</td></tr><tr><td><code>Others/</code></td><td>工具、CI、速查等</td></tr><tr><td><code>AI/</code></td><td>AI 相关</td></tr><tr><td><code>authors.yml</code></td><td>作者元数据</td></tr></tbody></table>
<p>当前约 <strong>17</strong> 篇 <code>.md</code> 文章（以仓库实际文件为准）。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tags">Tags<a href="https://blog.mengfei.tech/blog/AGENTS#tags" class="hash-link" aria-label="Direct link to Tags" title="Direct link to Tags" translate="no">​</a></h2>
<p>Frontmatter <code>tags</code> 只用<strong>英文小写 slug</strong>。Docusaurus 3 用 lodash <code>kebabCase</code> 生成标签页路径，所以标签字符串必须已经是目标 slug：<code>AI</code> 会落到 <code>/blog/tags/ai</code>，但 <code>TypeScript</code> 会落到 <code>/blog/tags/type-script</code>，和 <code>typescript</code> 拆成两页。</p>
<p>每篇一个主标签，与所在目录对齐；只有文章确实跨主题时再加次标签，最多 2 个。次标签也必须来自下表。不要再使用 <code>npm</code>、<code>yarn</code>、<code>ts</code>、<code>hooks</code>、<code>Powershell</code>、<code>Test</code>、<code>Jest</code> 等会拆页或与主标签重复的写法。文章 <code>slug</code> 保持不变，只改 <code>tags</code>。</p>
<table><thead><tr><th>目录</th><th>主标签</th><th>标签页</th></tr></thead><tbody><tr><td><code>AI/</code></td><td><code>ai</code></td><td><code>/blog/tags/ai</code></td></tr><tr><td><code>Docker/</code></td><td><code>docker</code></td><td><code>/blog/tags/docker</code></td></tr><tr><td><code>Linux/</code></td><td><code>linux</code></td><td><code>/blog/tags/linux</code></td></tr><tr><td><code>Nodejs/</code></td><td><code>nodejs</code></td><td><code>/blog/tags/nodejs</code></td></tr><tr><td><code>React/</code></td><td><code>react</code></td><td><code>/blog/tags/react</code></td></tr><tr><td><code>Ts/</code></td><td><code>typescript</code></td><td><code>/blog/tags/typescript</code></td></tr><tr><td><code>Windows/</code></td><td><code>windows</code></td><td><code>/blog/tags/windows</code></td></tr><tr><td><code>Others/</code></td><td>按内容选 <code>github</code> 或 <code>testing</code>；若正文属于上表已有主题（如 npm/yarn 命令速查），主标签用该主题（<code>nodejs</code>）</td><td><code>/blog/tags/&lt;slug&gt;</code></td></tr></tbody></table>
<p>导航「分类」下拉列出上表里已有文章的标签页。「AI」同时保留为顶栏第一项，仍指向 <code>/blog/tags/ai</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conventions">Conventions<a href="https://blog.mengfei.tech/blog/AGENTS#conventions" class="hash-link" aria-label="Direct link to Conventions" title="Direct link to Conventions" translate="no">​</a></h2>
<ul>
<li class="">新文章放在对应主题子目录，文件名可用中文；Docusaurus 会生成 slug。<code>tags</code> 按上一节填写，不要新开同义标签。</li>
<li class="">工具使用指南放在 <code>docs/guides/</code>（站点分类「技术文档」），不要放进 <code>blog/</code>。</li>
<li class="">建议在长文合适位置添加 <code>&lt;!-- truncate --&gt;</code>，否则 <code>pnpm build</code> 会警告 <code>onUntruncatedBlogPosts</code>（不阻断构建）。</li>
<li class="">文内锚点需与标题生成的 id 一致，否则可能出现 <code>onBrokenAnchors</code> 警告。</li>
<li class="">不要在此目录放非 Markdown 构建依赖或密钥。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-notes">Local Notes<a href="https://blog.mengfei.tech/blog/AGENTS#local-notes" class="hash-link" aria-label="Direct link to Local Notes" title="Direct link to Local Notes" translate="no">​</a></h2>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Docker常用命令]]></title>
            <link>https://blog.mengfei.tech/blog/used-commands</link>
            <guid>https://blog.mengfei.tech/blog/used-commands</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Docker常用命令]]></description>
            <category>docker</category>
        </item>
        <item>
            <title><![CDATA[Linux下nodejs安装源nodesource]]></title>
            <link>https://blog.mengfei.tech/blog/linux-install-nodejs</link>
            <guid>https://blog.mengfei.tech/blog/linux-install-nodejs</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Linux下nodejs安装源nodesource]]></description>
            <content:encoded><![CDATA[<p><a href="https://github.com/nodesource/distributions" target="_blank" rel="noopener noreferrer" class="">https://github.com/nodesource/distributions</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="常用">常用<a href="https://blog.mengfei.tech/blog/linux-install-nodejs#%E5%B8%B8%E7%94%A8" class="hash-link" aria-label="Direct link to 常用" title="Direct link to 常用" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="debian-and-ubuntu-based-distributions">Debian and Ubuntu based distributions<a href="https://blog.mengfei.tech/blog/linux-install-nodejs#debian-and-ubuntu-based-distributions" class="hash-link" aria-label="Direct link to Debian and Ubuntu based distributions" title="Direct link to Debian and Ubuntu based distributions" translate="no">​</a></h3>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Using Ubuntu</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sudo apt-get install -y nodejs</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Using Debian, as root</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">curl -fsSL https://deb.nodesource.com/setup_14.x | bash -</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">apt-get install -y nodejs</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enterprise-linux-based-distributions">Enterprise Linux based distributions<a href="https://blog.mengfei.tech/blog/linux-install-nodejs#enterprise-linux-based-distributions" class="hash-link" aria-label="Direct link to Enterprise Linux based distributions" title="Direct link to Enterprise Linux based distributions" translate="no">​</a></h3>
<p>Run on RHEL, CentOS, CloudLinux, Amazon Linux or Fedora:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># As root</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">curl -fsSL https://rpm.nodesource.com/setup_14.x | bash -</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># No root privileges</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">curl -fsSL https://rpm.nodesource.com/setup_14.x | sudo bash -</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>linux</category>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[NPM包开发KnowledgeMap]]></title>
            <link>https://blog.mengfei.tech/blog/npm-development-knowledgemap</link>
            <guid>https://blog.mengfei.tech/blog/npm-development-knowledgemap</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[给公司的文档库写了篇私库开发的 KnowledgeMap，从中摘取一部分。]]></description>
            <content:encoded><![CDATA[<p>给公司的文档库写了篇私库开发的 KnowledgeMap，从中摘取一部分。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="思考">思考：<a href="https://blog.mengfei.tech/blog/npm-development-knowledgemap#%E6%80%9D%E8%80%83" class="hash-link" aria-label="Direct link to 思考：" title="Direct link to 思考：" translate="no">​</a></h2>
<ol>
<li class="">当我们 npm i package 的时候之后，require 或 import 一个包的时时候，是如何寻找到这个包的。</li>
<li class="">当一个包，在项目中存在多个版本的情况，如何确定引入的是哪个版本。例如项目依赖了 packageA@3.0.0 和 packageB@1.0.0， 而packageB 又依赖了pacakgeA@2.0.0.</li>
<li class="">npm 包是如何提供一个命令的。例如， 当我们安装 npm -g nrm 的时候，为何会有nrm 命令产生。</li>
<li class="">如何手动发布一个npm 包到公网npm 仓库</li>
<li class="">包的版本如何定义</li>
<li class="">什么时候需要发布一个npm 包</li>
<li class="">什么时间节点需要发布一个 npm 包的新版本，新的版本又该如何定义。</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="正文">正文<a href="https://blog.mengfei.tech/blog/npm-development-knowledgemap#%E6%AD%A3%E6%96%87" class="hash-link" aria-label="Direct link to 正文" title="Direct link to 正文" translate="no">​</a></h2>
<p>由于上述问题，涉及到的内容略多，下是推荐和相关的知识点。</p>
<ol>
<li class="">nodejs的模块解析策略<!-- -->
<ol>
<li class=""><a href="http://nodejs.cn/api/modules.html" target="_blank" rel="noopener noreferrer" class="">http://nodejs.cn/api/modules.html</a></li>
<li class=""><a href="https://www.tslang.cn/docs/handbook/module-resolution.html" target="_blank" rel="noopener noreferrer" class="">https://www.tslang.cn/docs/handbook/module-resolution.html</a></li>
</ol>
</li>
<li class="">package.json 字段含义<!-- -->
<ol>
<li class=""><a href="https://docs.npmjs.com/cli/v6/configuring-npm/package-json" target="_blank" rel="noopener noreferrer" class="">https://docs.npmjs.com/cli/v6/configuring-npm/package-json</a></li>
<li class="">非官方扩展字段 不在基础node或浏览器环境下支持，但被某些包支持<!-- -->
<ul>
<li class="">module  指定esm module 的入口文件。 由rollup最早提出(<a href="https://github.com/rollup/rollup/wiki/pkg.module" target="_blank" rel="noopener noreferrer" class="">https://github.com/rollup/rollup/wiki/pkg.module</a>), webpack2.x之后版本开始支持</li>
<li class="">types, typings  指定包的d.ts的入口文件，由typescript 支持</li>
<li class="">unpkg  公网npm 包可以使用的的cdn  <a href="https://github.com/mjackson/unpkg" target="_blank" rel="noopener noreferrer" class="">https://github.com/mjackson/unpkg</a></li>
<li class="">sideEffects Webpack 支持的，用来标记副作用文件，是否可以被TreeShaking</li>
</ul>
</li>
</ol>
</li>
<li class="">esm module 和 cjs module 是什么， 有什么区别<!-- -->
<ol>
<li class="">esm <a href="https://tc39.es/ecma262/#sec-modules" target="_blank" rel="noopener noreferrer" class="">https://tc39.es/ecma262/#sec-modules</a></li>
<li class="">cjs <a href="http://nodejs.cn/api/modules.html" target="_blank" rel="noopener noreferrer" class="">http://nodejs.cn/api/modules.html</a></li>
</ol>
</li>
<li class="">命令的本质就是一个可执行文件，俗称脚本文件。nodejs 产生的js 脚本文件 在使用 #！ /user/bin/env node 指定脚本的运行者。如同shell 脚本需要在文件头指定运行者 #! /bin/bash 一样。<!-- -->
<ol>
<li class="">npm 发布相关命令   <a href="https://docs.npmjs.com/cli/v7/commands" target="_blank" rel="noopener noreferrer" class="">https://docs.npmjs.com/cli/v7/commands</a>
<ul>
<li class="">npm login</li>
<li class="">npm public</li>
<li class="">npm deprecate</li>
</ul>
</li>
</ol>
</li>
<li class="">npm 的语义化版本<!-- -->
<ol>
<li class=""><a href="https://docs.npmjs.com/about-semantic-versioning" target="_blank" rel="noopener noreferrer" class="">https://docs.npmjs.com/about-semantic-versioning</a></li>
<li class=""><a href="https://semver.org/" target="_blank" rel="noopener noreferrer" class="">https://semver.org</a></li>
</ol>
</li>
<li class="">了解包 semantic-release  系列的包 <a href="https://github.com/semantic-release/semantic-release" target="_blank" rel="noopener noreferrer" class="">https://github.com/semantic-release/semantic-release</a></li>
<li class="">了解 conventional-changelog 系列的包<!-- -->
<ol>
<li class=""><a href="https://www.conventionalcommits.org/" target="_blank" rel="noopener noreferrer" class="">https://www.conventionalcommits.org/</a></li>
<li class=""><a href="https://github.com/conventional-changelog" target="_blank" rel="noopener noreferrer" class="">https://github.com/conventional-changelog</a></li>
</ol>
</li>
</ol>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[Npm包安全检查]]></title>
            <link>https://blog.mengfei.tech/blog/npm-security-check</link>
            <guid>https://blog.mengfei.tech/blog/npm-security-check</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Npm包安全检查]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="前言---npm包安全问题">前言 - npm包安全问题<a href="https://blog.mengfei.tech/blog/npm-security-check#%E5%89%8D%E8%A8%80---npm%E5%8C%85%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98" class="hash-link" aria-label="Direct link to 前言 - npm包安全问题" title="Direct link to 前言 - npm包安全问题" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="细数历年npm包安全问题">细数历年npm包安全问题<a href="https://blog.mengfei.tech/blog/npm-security-check#%E7%BB%86%E6%95%B0%E5%8E%86%E5%B9%B4npm%E5%8C%85%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98" class="hash-link" aria-label="Direct link to 细数历年npm包安全问题" title="Direct link to 细数历年npm包安全问题" translate="no">​</a></h3>
<ul>
<li class="">2021年11月4日, npm包 coa被劫持, 大量react项目被影响. 【部分公司项目，在发布时因其影响而发布失败】</li>
<li class="">2021年10月22日, ua-parser-js被恶意劫持，多个版本植入挖矿脚本</li>
<li class="">2019年7月，有开发者在purescript npm 安装程序中发现一些恶意代码。原来是有攻击者获取了@shinnn（purescript npm 安装程序原始作者）的npm账户，随后在purescript npm安装程序中插入恶意代码。</li>
<li class="">2019年6月，黑客向 npm 发布一个“useful”的包（electron-native-notify），等到它被目标（某应用程序）使用后更新包内容，加入恶意代码。而某应用程序又是 Agama 加密货币钱包的一部分。</li>
<li class="">2018年11月，npm 下载量超过 200 万的 package 被注入了恶意代码，黑客利用该恶意代码访问热门 JavaScript 库，目标是 copay（开源比特币钱包）及其衍生产品的用户，以此窃取用户的数字货币。</li>
<li class="">2018年7月，黑客利用恶意代码破坏ESLint库。该恶意代码被设计用来窃取其他开发人员的npm证书。</li>
<li class="">2018年5月，黑客试图在名为getcookies的流行npm包中隐藏后门。</li>
</ul>
<p>除了上述恶意的黑客导致的安全问题外，某些npm包，有意或无意的存在各种各样的漏洞或bug。常见的如：DOS, REDOS, Prototype Pollution, XSS漏洞等等。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="社区解决方案">社区解决方案<a href="https://blog.mengfei.tech/blog/npm-security-check#%E7%A4%BE%E5%8C%BA%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88" class="hash-link" aria-label="Direct link to 社区解决方案" title="Direct link to 社区解决方案" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="npm-audit-npm6x">npm audit (npm@&gt;6.x)<a href="https://blog.mengfei.tech/blog/npm-security-check#npm-audit-npm6x" class="hash-link" aria-label="Direct link to npm audit (npm@>6.x)" title="Direct link to npm audit (npm@>6.x)" translate="no">​</a></h3>
<p>npm 收购nsp后推出的官方检查工具， 之前应该是基于nsp数据库。
目前基于 <a href="https://github.com/advisories" target="_blank" rel="noopener noreferrer" class="">https://github.com/advisories</a></p>
<p>npm audit 依赖于npm package-lock.json 或 npm-shrinkwrap.json</p>
<p>常用方法</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">npm audit # 只扫描，显示有问题的依赖包</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm audit fix #扫描并自动修复和安装符合兼容性要求的包</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm audit fix --package-lock-only #只修改package-lock.json 需要手动安装依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm audit fix --only=prod #扫描并修复</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm audit --audit-level=moderate #设置扫描报告等级</span><br></div></code></pre></div></div>
<p>检查报告，会包含有问题的包和版本信息，以及漏洞信息，漏洞的严重程度等等
<img decoding="async" loading="lazy" alt="检查报告" src="https://blog.mengfei.tech/assets/images/Lark20211128-165730-edb535587077eb73fe867f2fe974f844.png" width="1538" height="910" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="snyk">snyk<a href="https://blog.mengfei.tech/blog/npm-security-check#snyk" class="hash-link" aria-label="Direct link to snyk" title="Direct link to snyk" translate="no">​</a></h3>
<p>snyk是一家美国的网络安全公司，有自己的安全数据库
同时支持yarn 和 npm</p>
<p>snyk cli 工具是该公司的开源项目<a href="https://github.com/snyk/snyk" target="_blank" rel="noopener noreferrer" class="">https://github.com/snyk/snyk</a></p>
<p>基础使用方法</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># 安装</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm i -g snyk</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 登录, snyk cli 依赖于snyk.io 提供的api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">snyk auth</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 扫描</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">snyk test</span><br></div></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="检查报告" src="https://blog.mengfei.tech/assets/images/Lark20211128-163432-688d259a82cd6f360ae6d42a2dba7f32.png" width="1011" height="644" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="snyk-和-npm-audit的对比">snyk 和 npm audit的对比<a href="https://blog.mengfei.tech/blog/npm-security-check#snyk-%E5%92%8C-npm-audit%E7%9A%84%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="Direct link to snyk 和 npm audit的对比" title="Direct link to snyk 和 npm audit的对比" translate="no">​</a></h3>
<p>这个是snyk公司出的功能对比
<img decoding="async" loading="lazy" alt="检查报告" src="https://blog.mengfei.tech/assets/images/npm-vs-snyk-40d2de54a63a4b8001bd398fa454c771.png" width="1818" height="876" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="观点">观点<a href="https://blog.mengfei.tech/blog/npm-security-check#%E8%A7%82%E7%82%B9" class="hash-link" aria-label="Direct link to 观点" title="Direct link to 观点" translate="no">​</a></h3>
<p>定期或脚本的检查依赖，更新依赖是有必要的，且没有太大成本的。
像前段时间的 ua-parser-js 和 coa事件，都会被上述两种方案所收录。
脚本化的检查，可以在一定程度上避免一些已经被发现的有问题的包，所导致的安全问题。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="常用依赖检查命令">常用依赖检查命令<a href="https://blog.mengfei.tech/blog/npm-security-check#%E5%B8%B8%E7%94%A8%E4%BE%9D%E8%B5%96%E6%A3%80%E6%9F%A5%E5%91%BD%E4%BB%A4" class="hash-link" aria-label="Direct link to 常用依赖检查命令" title="Direct link to 常用依赖检查命令" translate="no">​</a></h3>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">yarn why &lt;pkg&gt; # 查看某npm包依赖关系，项目必须包含yarn.lock</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info [pkg] [package.json field] # 查看某包的信息，不传包名，显示当前项目的package.json信息。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info chalk versions # 查看 chalk 目前npm提供的所有版本</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info chalk@4.0.0 dependencies # 查看 chalk 4.0.0版本的生产依赖 </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm ls #查看项目依赖树</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm ls [pkg] #查看某包的依赖树</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm ls --depth 1 #限定展示依赖层级</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">npm outdated #查看项目哪些依赖需要更新</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="推荐一个检查依赖的第三方包-npm-check-updates">推荐一个检查依赖的第三方包 npm-check-updates<a href="https://blog.mengfei.tech/blog/npm-security-check#%E6%8E%A8%E8%8D%90%E4%B8%80%E4%B8%AA%E6%A3%80%E6%9F%A5%E4%BE%9D%E8%B5%96%E7%9A%84%E7%AC%AC%E4%B8%89%E6%96%B9%E5%8C%85-npm-check-updates" class="hash-link" aria-label="Direct link to 推荐一个检查依赖的第三方包 npm-check-updates" title="Direct link to 推荐一个检查依赖的第三方包 npm-check-updates" translate="no">​</a></h3>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">npm i -g npm-check-updates</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ncu # 检查项目所有依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ncu -u #检查并更新package.json 需要手动安装依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ncu "/.*scope.*/" #检查包含scope关键字的包</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ncu -u "/.*scope.*/" #检查包含scope关键字的包,并更新package.json 需要手动安装依赖</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[Npm源管理]]></title>
            <link>https://blog.mengfei.tech/blog/npm-resource-manager</link>
            <guid>https://blog.mengfei.tech/blog/npm-resource-manager</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Npm源管理, npm, yarn, nrm, yrm]]></description>
            <content:encoded><![CDATA[<p>NPM: <a href="https://www.npmjs.com/package/ynrm" target="_blank" rel="noopener noreferrer" class="">https://www.npmjs.com/package/ynrm</a>
Github: <a href="https://github.com/mengfei0053/ynrm.git" target="_blank" rel="noopener noreferrer" class="">https://github.com/mengfei0053/ynrm.git</a></p>
<p>Fork了狼叔yrm做了一些修改, 可以同时更改yarn 和npm 当前用户的源。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ynrm-和-nrmyrm">Ynrm 和. Nrm/Yrm<a href="https://blog.mengfei.tech/blog/npm-resource-manager#ynrm-%E5%92%8C-nrmyrm" class="hash-link" aria-label="Direct link to Ynrm 和. Nrm/Yrm" title="Direct link to Ynrm 和. Nrm/Yrm" translate="no">​</a></h2>
<ul>
<li class="">用 typescript 重写了一下</li>
<li class="">将npm从依赖中移除, 通过<code>npm root -g</code>,获取本机的npm</li>
<li class="">使用axios替换request</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="安装">安装<a href="https://blog.mengfei.tech/blog/npm-resource-manager#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="Direct link to 安装" title="Direct link to 安装" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">$ npm install -g ynrm</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example">Example<a href="https://blog.mengfei.tech/blog/npm-resource-manager#example" class="hash-link" aria-label="Direct link to Example" title="Direct link to Example" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">ynrm ls # 查看源</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">* npm -----  https://registry.npmjs.org/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  cnpm ----  http://r.cnpmjs.org/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  taobao --  https://registry.npm.taobao.org/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  nj ------  https://registry.nodejitsu.com/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  rednpm --  http://registry.mirror.cqupt.edu.cn</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  skimdb --  https://skimdb.npmjs.com/registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  yarn ----  https://registry.yarnpkg.com</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># ynrm will set up both npm registy and yarn registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># switch registry to taobao registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ynrm use cnpm # 使用源</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    YARN Registry has been set to: https://registry.npm.taobao.org/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    NPM Registry has been set to: https://registry.npm.taobao.org/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ynrm add custom_registry https://custom_registry.xx.com # 添加仓库源</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ynrm del custom_registry # 删除仓库源</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ynrm test # 测试仓库源链接速度</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="usage">Usage<a href="https://blog.mengfei.tech/blog/npm-resource-manager#usage" class="hash-link" aria-label="Direct link to Usage" title="Direct link to Usage" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Usage: ynrm [options] [command]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Commands:</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ls                           List all the registries</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    use &lt;registry&gt;               Change registry to registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    add &lt;registry&gt; &lt;url&gt; [home]  Add one custom registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    del &lt;registry&gt;               Delete one custom registry</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    home &lt;registry&gt; [browser]    Open the homepage of registry with optional browser</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    test [registry]              Show the response time for one or all registries</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    help                         Print this help</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Options:</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    -h, --help     output usage information</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    -V, --version  output the version number</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="默认可选仓库源">默认可选仓库源<a href="https://blog.mengfei.tech/blog/npm-resource-manager#%E9%BB%98%E8%AE%A4%E5%8F%AF%E9%80%89%E4%BB%93%E5%BA%93%E6%BA%90" class="hash-link" aria-label="Direct link to 默认可选仓库源" title="Direct link to 默认可选仓库源" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://www.npmjs.org/" target="_blank" rel="noopener noreferrer" class="">npm</a></li>
<li class=""><a href="http://cnpmjs.org/" target="_blank" rel="noopener noreferrer" class="">cnpm</a></li>
<li class=""><a href="https://www.nodejitsu.com/" target="_blank" rel="noopener noreferrer" class="">nodejitsu</a></li>
<li class=""><a href="https://mirrors.cloud.tencent.com/npm/" target="_blank" rel="noopener noreferrer" class="">tencent</a></li>
<li class=""><a href="http://npm.taobao.org/" target="_blank" rel="noopener noreferrer" class="">taobao</a></li>
<li class=""><a href="http://npm.mirror.cqupt.edu.cn/" target="_blank" rel="noopener noreferrer" class="">rednpm</a></li>
<li class=""><a href="https://registry.yarnpkg.com/" target="_blank" rel="noopener noreferrer" class="">yarn</a></li>
</ul>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[从npm-shrinkwrap 到 package-lock]]></title>
            <link>https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock</link>
            <guid>https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[关于 shrinkwrap 的更新]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关于-shrinkwrap-的更新">关于 shrinkwrap 的更新<a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#%E5%85%B3%E4%BA%8E-shrinkwrap-%E7%9A%84%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="Direct link to 关于 shrinkwrap 的更新" title="Direct link to 关于 shrinkwrap 的更新" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v1316v2152"><a href="https://github.com/npm/cli/blob/v2.15.12/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">v1.3.16~v2.15.2</a><a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#v1316v2152" class="hash-link" aria-label="Direct link to v1316v2152" title="Direct link to v1316v2152" translate="no">​</a></h3>
<ul>
<li class="">v1.3.16 (2013-12-11):<!-- -->
<ul>
<li class="">Stopped re-downloading URL and shrinkwrap dependencies, as demonstrated in #3463 (644c2ff, @spmason). You can use the --force option to force re-download and installation of all dependencies.</li>
</ul>
</li>
<li class="">v1.4.1 (2014-02-13):<!-- -->
<ul>
<li class="">Fix npm shrinkwrap forgetting to shrinkwrap dependencies that were also development dependencies</li>
</ul>
</li>
<li class="">v1.4.3 (2014-02-16):<!-- -->
<ul>
<li class="">Make npm shrinkwrap output dependencies in a sorted order, so that diffs between shrinkwrap files should be saner now. (059b2bf, @Raynos)</li>
</ul>
</li>
<li class="">v1.4.7 (2014-04-15):<!-- -->
<ul>
<li class="">Fix npm crashing when doing npm shrinkwrap in the presence of a package.json with no dependencies. (a9d9fa5, @kislyuk)</li>
</ul>
</li>
<li class="">v2.1.8 (2014-11-06):<!-- -->
<ul>
<li class="">063d843 npm version now updates version in npm-shrinkwrap.json (@faiq)</li>
<li class="">3f53cd7 #6559 save local dependencies in npm-shrinkwrap.json (@Torsph)</li>
</ul>
</li>
<li class="">v2.1.13 (2014-12-11):<!-- -->
<ul>
<li class="">cb6ff8d #6879 npm version: Update shrinkwrap post-check. (@othiym23)</li>
</ul>
</li>
<li class="">v2.1.17 (2014-12-25):<!-- -->
<ul>
<li class="">6b7c5ec #7011 Send auth for tarball fetches for packages in npm-shrinkwrap.json from private registries. (@othiym23)</li>
</ul>
</li>
<li class="">v2.7.1 (2015-03-05):<!-- -->
<ul>
<li class="">6823807 #7121 npm install --save for Git dependencies saves the URL passed in, instead of the temporary directory used to clone the remote repo. Fixes using Git dependencies when shrinkwrapping. In the process, rewrote the Git dependency caching code. Again. No more single-letter variable names, and a much clearer workflow. (@othiym23)</li>
</ul>
</li>
<li class="">v2.7.3 (2015-03-16):<!-- -->
<ul>
<li class="">1549106 #7641 Due to 448efd0, running npm shrinkwrap --dev caused production dependencies to no longer be included in npm-shrinkwrap.json. Whoopsie! (@othiym23)</li>
</ul>
</li>
<li class="">v2.8.3 (2015-04-15):<!-- -->
<ul>
<li class="">387f889 #7961 Ensure that hosted git SSH URLs always have a valid protocol when stored in resolved fields in npm-shrinkwrap.json. (@othiym23)</li>
</ul>
</li>
<li class="">v2.9.1 (2015-04-30):<!-- -->
<ul>
<li class="">b574076 #8079 Make the npm shrinkwrap documentation use code formatting for examples consistently. It would be great to do this for more commands HINT HINT. (@RichardLitt)</li>
</ul>
</li>
<li class="">v2.11.0 (2015-05-21):<!-- -->
<ul>
<li class="">f87cde5 #8292 Fix typo in an example and grammar in the description in the shrinkwrap documentation. (@vshih)</li>
<li class="">d3526ce Improve the formatting in the shrinkwrap documentation. (@othiym23)</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v300v31010"><a href="https://github.com/npm/cli/blob/v3.10.10/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">v3.0.0~v3.10.10</a><a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#v300v31010" class="hash-link" aria-label="Direct link to v300v31010" title="Direct link to v300v31010" translate="no">​</a></h3>
<ul>
<li class="">v3.0.0 (2015-06-25):<!-- -->
<ul>
<li class="">Install: it works different!<!-- -->
<ul>
<li class="">#6928 (#2931 #2950) npm install when you have an npm-shrinkwrap.json will ensure you have the modules specified in it are installed in exactly the shape specified no matter what you had when you started.</li>
<li class="">#6913 (#1341 #3124 #4956 #6349 #5465) npm install when some of your dependencies are missing sub-dependencies will result in those sub-dependencies being installed. That is, npm install now knows how to fix broken installs, most of the time.</li>
<li class="">#5465 If you directly npm install a module that's already a subdep of something else and your new version is incompatible, it will now install the previous version nested in the things that need it.</li>
<li class="">a2b50cf #5693 When installing a new module, if it's mentioned in your npm-shrinkwrap.json or your package.json use the version specifier from there if you didn't specify one yourself.</li>
</ul>
</li>
<li class="">Shrinkwraps: they are a-changin'!<!-- -->
<ul>
<li class="">First of all, they should be idempotent now (#5779). No more differences because the first time you install (without npm-shrinkwrap.json) and the second time (with npm-shrinkwrap.json).</li>
<li class="">#6781 Second, if you save your changes to package.json and you have npm-shrinkwrap.json, then it will be updated as well. This applies to all of the commands that update your tree:<!-- -->
<ul>
<li class="">npm install --save</li>
<li class="">npm update --save</li>
<li class="">npm dedupe --save (#6410)</li>
<li class="">npm uninstall --save</li>
</ul>
</li>
<li class="">#4944 (#5161 #5448) Third, because node_modules folders are now deduped and flat, shrinkwrap has to also be smart enough to handle this.</li>
<li class="">And finally, enjoy this shrinkwrap bug fix:<!-- -->
<ul>
<li class="">#3675 When shrinkwrapping a dependency that's both a devDependency and the child of a regular dependency, npm now correctly includes the child.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class="">v3.1.0 (2015-07-02):</li>
<li class="">57c3cea #8695 Remote packages with shrinkwraps made npm cause node + iojs to explode and catch fire. NO MORE. (@iarna)</li>
<li class="">v3.3.0 (2015-08-13):<!-- -->
<ul>
<li class="">As shrinkwraps don't include dev deps by default. This replaces passing in --dev in that scenario.</li>
</ul>
</li>
<li class="">v3.3.7 (2015-10-08):<!-- -->
<ul>
<li class="">87336c3 #9879 npm@3's shrinkwrap was refusing to shrinkwrap if an optional dependency was missing– patch it to allow this. (@mantoni)</li>
</ul>
</li>
<li class="">v3.3.10 (2015-10-22):<!-- -->
<ul>
<li class="">SHRINKWRAP + DEV DEPS NOW RESPECTED</li>
<li class="">eb28a8c #9647 If a shrinkwrap already has dev deps, don't throw them away when someone later runs npm install --save. (@iarna)</li>
</ul>
</li>
<li class="">v3.3.11 (2015-10-29):<!-- -->
<ul>
<li class="">PARTIAL SHRINKWRAPS, NO LONGER A BAD DAY</li>
<li class="">We're ignoring the version check on things specified in the shrinkwrap so that you can override the version that will be installed. This is because you may want to use a different version than is specified by your dependencies' dependencies' package.json files.</li>
</ul>
</li>
<li class="">v3.7.3 (2016-02-11):<!-- -->
<ul>
<li class="">42a4727 #11391 Fixed versions of shrinkwrap.json in examples in documentation for npm shrinkwrap, which did not quite match up. (@xcatliu)</li>
</ul>
</li>
<li class="">v3.8.9 (2016-04-28)：<!-- -->
<ul>
<li class="">60da618 #12347 Fix a bug that could result in shrinkwraps missing the resolved field, which is necessary in producing a fully reproducible build. (@sminnee)</li>
</ul>
</li>
<li class="">v3.9.1 (2016-05-12)：<!-- -->
<ul>
<li class="">b894413 #12372 Changing a nested dependency in an npm-shrinkwrap.json and then running npm install would not get up the updated package. This corrects that. (@misterbyrne)</li>
</ul>
</li>
<li class="">v3.9.2 (2016-05-17):<!-- -->
<ul>
<li class="">This is a quick patch release. The previous release, 3.9.1, introduced a bug where npm would crash given a combination of specific package tree on disk and a shrinkwrap.</li>
<li class="">cde367f #12724 Fix crasher when inflating shrinkwraps with packages on disk that were installed by older npm versions. (@iarna)</li>
</ul>
</li>
<li class="">v3.10.0 (2016-06-16):<!-- -->
<ul>
<li class="">NEW LIFECYCLE SCRIPT: shrinkwrap</li>
<li class="">e8c80f2 #10744 You can now add preshrinkwrap, shrinkwrap and postshrinkwrap to your package.json scripts section. They are run when you run npm shrinkwrap or npm install --save with an npm-shrinkwrap.json present in your module directory.</li>
<li class="">preshrinkwrap and shrinkwrap is run prior to generating the new npm-shrinkwrap.json and postshrinkwrap is run after. (@SimenB)</li>
</ul>
</li>
<li class="">v3.10.4 (2016-06-30):<!-- -->
<ul>
<li class="">SHRINKWRAP IS COMPLICATED BUT IT'S BETTER NOW</li>
<li class="">@iarna did some heroic hacking to refactor a bunch of shrinkwrap-related bits and fixed some resolution and pathing issues that were biting users. The code around that stuff got more readable/maintainable in the process, too!</li>
<li class="">346bba1 #13214 Resolve local dependencies in npm-shrinkwrap.json relative to the top of the tree. (@iarna)</li>
<li class="">4a67fdb #13213 If you run npm install modulename it should, if a npm-shrinkwrap.json is present, use the version found there. If not, it'll use the version found in your package.json, and failing that, use latest. This fixes a case where the first check was being bypassed because version resolution was being done prior to loading the shrinkwrap, and so checks to match the shrinkwrap version couldn't succeed. (@iarna)</li>
<li class="">afa2133 #13214 Refactor shrinkwrap specifier lookup into shared function. (@iarna)</li>
<li class="">2820b56 #13214 Refactor operations in inflate-shrinkwrap.js into separate functions for added clarity. (@iarna)</li>
<li class="">ee5bfb3 Fix Windows path issue in a shrinkwrap test. (@zkat)</li>
</ul>
</li>
<li class="">v3.10.6 (2016-07-07):<!-- -->
<ul>
<li class="">This week we have a bunch of bug fixes for ya! A shrinkwrap regression introduced in 3.10.0, better lifecycle PATH behavior, improvements when working with registries other than registry.npmjs.org and a fix for hopefully the last don't print a progress bar over my interactive thingy bug.</li>
<li class="">SHRINKWRAP AND DEV DEPENDENCIES</li>
<li class="">The rewrite in 3.10.0 triggered a bug where dependencies of devDependencies would be included in your shrinkwrap even if you didn't request devDependencies.</li>
<li class="">2484529 #13308 Fix bug where deps of devDependencies would be incorrectly included in shrinkwraps. (@iarna)</li>
</ul>
</li>
<li class="">v3.10.7 (2016-08-11):<!-- -->
<ul>
<li class="">BETTER SHRINKWRAP WITH GIT DEPENDENCIES<!-- -->
<ul>
<li class="">0f7e319 #12718 Update outdated git dependencies found in shrinkwraps. Previously, if the module version was the same then no update would be completed even if the committish had changed. (@kossnocorp)</li>
</ul>
</li>
</ul>
</li>
<li class="">v3.10.8 (2016-09-08):<!-- -->
<ul>
<li class="">SHRINKWRAP LEVEL UP</li>
<li class="">The most notable part of this release is a series of commits meant to make npm shrinkwrap more consistent. By itself, shrinkwrap seems like a fairly straightforward thing to implement, but things get complicated when it starts interacting with devDependencies, optionalDependencies, and bundledDependencies. These commits address some corner cases related to these.<!-- -->
<ul>
<li class="">a7eca32 #10073 Record if a dependency is only used as a devDependency and exclude it from the shrinkwrap file. (@bengl)</li>
<li class="">1eabcd1 #10073 Record if a dependency is optional to shrinkwrap. (@bengl)</li>
<li class="">03efc89 #13692 We were doing a weird thing where we used a package.json field installable to check to see if we'd checked for platform compatibility, and if not did so. But this was the only place that was ever done so there was no reason to implement it in such an obfuscated manner. Instead it now just directly checks and then records that its done so on the node object with knownInstallable. This is useful to know because modules expanded via shrinkwrap don't go through this– inflateShrinkwrap does not currently have any rollback semantics and so checking this sort of thing there is unhelpful. (@iarna)</li>
<li class="">ff87938 #11735 Running npm install --save-dev will now update shrinkwrap file, but only if there already are devDependencies in it. (@szimek)</li>
<li class="">c00ca3a #13394 Check installability of modules from shrinkwrap, since modules that came into the tree vie shrinkwrap won't already have this information recorded in advance. (@iarna)</li>
</ul>
</li>
</ul>
</li>
<li class="">v3.10.9 (2016-10-06):<!-- -->
<ul>
<li class="">LIFECYCLE FIXES<!-- -->
<ul>
<li class="">d388f90 #13942 Fix current working directory while running shrinkwrap lifecycle scripts. Previously if you ran a shrinkwrap from another lifecycle script AND node_modules existed (and if you're running npm shrinkwrap it probably should) then npm would run the shrinkwrap lifecycle from the node_modules folder instead of the package folder. (@evocateur) (@iarna)</li>
<li class="">c3b6cdf #13964 Fix bug where the uninstall lifecycles weren't being run when you reinstalled/updated an existing module. (@iarna)</li>
<li class="">72bb89c #13344 When running lifecycles use TMPDIR if it's writable and fall back to the current working directory if not. Previously we just assumed TMPDIR wouldn't be writable (as we might have been running as nobody and nobody on some systems can't write to TMPDIR). (@aaronjensen)</li>
</ul>
</li>
<li class="">SHRINKWRAP GIT &amp; TAGGED DEPENDENCY FIX<!-- -->
<ul>
<li class="">3b5eee0 #13941 Fix git and tagged dependency matching with shrinkwraps. Previously git and tag (ie foo@latest) dependencies installed from a shrinkwrap would always be flagged as invalid. (@iarna)</li>
</ul>
</li>
</ul>
</li>
<li class="">v3.10.10 (2016-11-04):<!-- -->
<ul>
<li class="">See the discussion on #14042 for more context on this release, which is intended to address a serious regression in shrinkwrap behavior in the version of the CLI currently bundled with Node.js 6 LTS "Boron". You should never install this version directly; instead update to npm@4, which has everything in this release and more.</li>
<li class="">REGRESSION FIX<!-- -->
<ul>
<li class="">9aebe98 #14117 Fixes a bug where installing a shrinkwrapped package would fail if the platform failed to install an optional dependency included in the shrinkwrap. (@watilde)</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v400v461"><a href="https://github.com/npm/cli/blob/v4.6.1/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">v4.0.0~v4.6.1</a><a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#v400v461" class="hash-link" aria-label="Direct link to v400v461" title="Direct link to v400v461" translate="no">​</a></h3>
<ul>
<li class="">v4.0.0 (2016-10-20):<!-- -->
<ul>
<li class="">Partial shrinkwraps are no longer supported. npm-shrinkwrap.json is considered a complete installation manifest except for devDependencies.</li>
<li class="">BUGFIXES<!-- -->
<ul>
<li class="">bc84012 #14117 Fixes a bug where installing a shrinkwrapped package would fail if the platform failed to install an optional dependency included in the shrinkwrap. (@watilde)</li>
</ul>
</li>
<li class="">NO MORE PARTIAL SHRINKWRAPS (BREAKING)<!-- -->
<ul>
<li class="">That's right. No more partial shrinkwraps. That means that if you have an npm-shrinkwrap.json in your project, npm will no longer install anything that isn't explicitly listed there, unless it's a devDependency. This will open doors to some nice optimizations and make use of npm shrinkwrap just generally smoother by removing some awful corner cases. We will also skip devDependency installation from package.json if you added devDependencies to your shrinkwrap by using npm shrinkwrap --dev.</li>
<li class="">b7dfae8 #14327 Use readShrinkwrap to read top level shrinkwrap. There's no reason for npm to be doing its own bespoke heirloom-grade artisanal thing here. (@iarna)</li>
<li class="">0ae1f4b 4a54997 f22a1ae 3f61189 #14327 Treat shrinkwrap as canonical. That is, don't try to fill in for partial shrinkwraps. Partial shrinkwraps should produce partial installs. If your shrinkwrap contains NO devDependencies then we'll still try to install them from your package.json instead of assuming you NEVER want devDependencies. (@iarna)</li>
</ul>
</li>
</ul>
</li>
<li class="">v4.0.2 (2016-11-03):<!-- -->
<ul>
<li class="">SMALLER CHANGES<!-- -->
<ul>
<li class="">7f41295 #14519 Document that as of npm@4.0.1, npm shrinkwrap now includes devDependencies unless instructed otherwise. (@iarna)</li>
</ul>
</li>
</ul>
</li>
<li class="">v4.5.0 (2017-03-24):<!-- -->
<ul>
<li class="">NO SHRINKWRAP, NO PROBLEM<!-- -->
<ul>
<li class="">Previously we needed to extract every package's tarball to look for an npm-shrinkwrap.json before we could begin working through what its dependencies were. This was one of the things stopping npm's network accesses from happening more concurrently. The new filtered package metadata provides a new key, _hasShrinkwrap. When that's set to false then we know we don't have to look for one.</li>
</ul>
</li>
<li class="">4f5060eb3 #15969 Add support for skipping npm-shrinkwrap.json extraction when the registry can affirm that one doesn't exist. (@iarna)</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v500v5100-开始引入-package-lockjson"><a href="https://github.com/npm/cli/blob/v5.10.0/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">v5.0.0~v5.10.0</a> (开始引入 package-lock.json)<a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#v500v5100-%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5-package-lockjson" class="hash-link" aria-label="Direct link to v500v5100-开始引入-package-lockjson" title="Direct link to v500v5100-开始引入-package-lockjson" translate="no">​</a></h3>
<ul>
<li class="">v5.0.0 (2017-05-25):<!-- -->
<ul>
<li class="">npm will --save by default now. Additionally, package-lock.json will be automatically created unless an npm-shrinkwrap.json exists. (#15666)</li>
<li class="">package locks no longer exclude optionalDependencies that failed to build. This means package-lock.json and npm-shrinkwrap.json should now be cross-platform. (#15900)</li>
<li class="">Shrinkwrap and package-lock no longer warn and exit without saving the lockfile.</li>
<li class="">A new, standardised lockfile feature meant for cross-package-manager compatibility (package-lock.json), and a new format and semantics for shrinkwrap. (#16441)</li>
<li class="">--save is no longer necessary. All installs will be saved by default. You can prevent saving with --no-save. Installing optional and dev deps is unchanged: use -D/--save-dev and -O/--save-optional if you want them saved into those fields instead. Note that since npm@3, npm will automatically update npm-shrinkwrap.json when you save: this will also be true for package-lock.json. (#15666)</li>
<li class="">Indentation is now detected and preserved for package.json, package-lock.json, and npm-shrinkwrap.json. If the package lock is missing, it will default to package.json's current indentation.</li>
</ul>
</li>
<li class="">v5.0.4 (2017-06-13):<!-- -->
<ul>
<li class="">800cb2b4e #17076 Use legacy from field to improve upgrade experience from legacy shrinkwraps and installs. (@zkat)</li>
</ul>
</li>
<li class="">v5.1.0 (2017-07-05):<!-- -->
<ul>
<li class="">4f45ba222 a48958598 901bef0e1 #17508 Add a new requires field to package-lock.json with information about the logical dependency tree. This includes references to the specific version each package is intended to see, and can be used for many things, such as converting package-lock.json to other lockfile formats, various optimizations, and verifying correctness of a package tree. (@iarna)</li>
<li class="">3b4681b53 #17508 Stop calling addBundle on locked deps, speeding up the package-lock.json-based fast path. (@iarna)</li>
<li class="">It introduces a new package-lock.json field, called requires, which tracks which modules a given module requires.</li>
<li class="">It fixes #16866, allowing the package.json to trump the package-lock.json.</li>
<li class="">47e8fc8eb #17508 Make npm ls take package locks (and shrinkwraps) into account. This means npm ls can now be used to see which dependencies are missing, so long as a package lock has been previously generated with it in. (@iarna)</li>
<li class="">99ef3b52c #17505 Stop trying to commit updated npm-shrinkwrap.json and package-lock.json if they're .gitignored. (@zkat)</li>
</ul>
</li>
<li class="">v5.2.0 (2017-07-05): （开始加入npx）<!-- -->
<ul>
<li class="">c0a289b1b #17606 Make sure that when write package.json and package-lock.json we always use unix path separators. (@Standard8)</li>
</ul>
</li>
<li class="">v5.4.0 (2017-08-22):<!-- -->
<ul>
<li class="">b6d5549d2 #17844 Make package-lock.json sorting locale-agnostic. Previously, sorting would vary by locale, due to using localeCompare for key sorting. This'll give you a little package-lock.json churn as it reshuffles things, sorry! (@LotharSee)</li>
</ul>
</li>
<li class="">v5.6.0 (2017-11-27):<!-- -->
<ul>
<li class="">bc263c3fd #19054 Fully cross-platform package-lock.json. Installing a failing optional dependency on one platform no longer removes it from the dependency tree, meaning that package-lock.json should now be generated consistently across platforms! 🎉 (@iarna)</li>
<li class="">f94fcbc50 #19160 Add --package-lock-only config option. This makes it so you can generate a target package-lock.json without performing a full install of node_modules. (@alopezsanchez)</li>
<li class="">a93e0a51d #18846 Correctly save transitive dependencies when using npm update in package-lock.json. (@iarna)</li>
</ul>
</li>
<li class="">v5.7.0 (2018-02-20):<!-- -->
<ul>
<li class="">Allow npm install to fix package-lock.json and npm-shrinkwrap.json files that have merge conflicts in them without your having to edit them. It works in conjunction with npm-merge-driver to entirely eliminate package-lock merge conflicts.</li>
<li class="">e27674c22 Automatically resolve merge conflicts in lock-files. (@zkat)</li>
</ul>
</li>
<li class="">v5.8.0 (2018-03-08):<!-- -->
<ul>
<li class="">2f513fe1c #19904 Make a best-attempt at preserving line ending style when saving package.json/package-lock.json/npm-shrinkwrap.json. This goes hand-in-hand with a previous patch to preserve detected indentation style. (@tuananh)</li>
<li class="">d3cfd41a2 pacote@7.6.1 (@zkat)<!-- -->
<ul>
<li class="">Enable file:-based resolved URIs in package-lock.json.</li>
<li class="">Retry git-based operations on certain types of failure.</li>
</ul>
</li>
<li class="">fc8761daf #19629 Give more detailed, contextual information when npm fails to parse package-lock.json and npm-shrinkwrap.json, instead of saying JSON parse error and leaving you out in the cold. (@JoshuaKGoldberg)</li>
</ul>
</li>
<li class="">v5.9.0 (2018-03-23):<!-- -->
<ul>
<li class="">If you resolve a package-lock.json merge conflict with npm install we now suggest you setup a merge driver to handle these automatically for you. If you're reading this and you'd like to set it up now, run:</li>
<li class="">npx npm-merge-driver install -g</li>
<li class="">5ebe99719 #20071 suggest installing the merge driver (@zkat)</li>
</ul>
</li>
<li class="">v5.10.0-next.0 (2018-04-12):<!-- -->
<ul>
<li class="">f18be9b39 #20154 Let version succeed when package-lock.json is gitignored. (@nwoltman)</li>
<li class="">8e21b19a8 #20140 Note in documentation that package-lock.json version gets touched by npm version. (@srl295)</li>
</ul>
</li>
<li class="">v5.10.0-next.1 (2018-05-07):<!-- -->
<ul>
<li class="">SHRONKWRAPS AND LACKFILES</li>
<li class="">If a published modules had legacy npm-shrinkwrap.json we were saving ordinary registry dependencies (name@version) to your package-lock.json as https:// URLs instead of versions.<!-- -->
<ul>
<li class="">36f998411 When saving the lock-file compute how the dependency is being required instead of using _resolved in the package.json. This fixes the bug that was converting registry dependencies into https:// dependencies. (@iarna)</li>
<li class="">113e1a3af When encountering a https:// URL in our lockfiles that point at our default registry, extract the version and use them as registry dependencies. This lets us heal package-lock.json files produced by 6.0.0 (@iarna)</li>
</ul>
</li>
<li class="">MORE package-lock.json FORMAT CHANGES?!<!-- -->
<ul>
<li class="">074502916 #20384 Add from field back into package-lock for git dependencies. This will give npm the information it needs to figure out whether git deps are valid, specially when running with legacy install metadata or in --package-lock-only mode when there's no node_modules. This should help remove a significant amount of git-related churn on the lock-file. (@zkat)</li>
</ul>
</li>
<li class="">1b535cb9d #20358 npm install-test (aka npm it) will no longer generate package-lock.json when running with --no-package-lock or package-lock=false. (@raymondfeng)</li>
<li class="">268f7ac50 5f84ebdb6 c12e61431 #20390 Fix a scenario where a git dependency had a comittish associated with it that was not a complete commitid. npm would never consider that entry in the package.json as matching the entry in the package-lock.json and this resulted in inappropriate pruning or reinstallation of git dependencies. This has been addressed in two ways, first, the addition of the from field as described in #20384 means we can exactly match the package.json. Second, when that's missing (when working with older package-lock.json files), we assume that the match is ok. (If it's not, we'll fix it up when a real installation is done.) (@iarna)</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v600-0v61415"><a href="https://github.com/npm/cli/blob/v5.10.0/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">v6.0.0-0~v6.14.15</a><a href="https://blog.mengfei.tech/blog/from-shrinkwrap-to-pkg-lock#v600-0v61415" class="hash-link" aria-label="Direct link to v600-0v61415" title="Direct link to v600-0v61415" translate="no">​</a></h3>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[npm-shrinkwrap.json、package-lock.json和yarn.loc]]></title>
            <link>https://blog.mengfei.tech/blog/fe-lock</link>
            <guid>https://blog.mengfei.tech/blog/fe-lock</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[初始]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="初始">初始<a href="https://blog.mengfei.tech/blog/fe-lock#%E5%88%9D%E5%A7%8B" class="hash-link" aria-label="Direct link to 初始" title="Direct link to 初始" translate="no">​</a></h2>
<p>锁版本的起始
npm v1.1.2 版本， 2012年2月25号 <a href="https://github.com/npm/cli/commit/d54ce3154dfe5283fcfeffc13d4e003bbade6370#diff-160056e00187b4f9fa30cb1ccf52d15febbae3f425abb1cf72a5e56b388d2a67" target="_blank" rel="noopener noreferrer" class="">https://github.com/npm/cli/commit/d54ce3154dfe5283fcfeffc13d4e003bbade6370#diff-160056e00187b4f9fa30cb1ccf52d15febbae3f425abb1cf72a5e56b388d2a67</a>
这个commit 开始 添加了 npm shrinkwrap
<a href="https://github.com/npm/cli/blob/v1.1.2/doc/cli/shrinkwrap.md" target="_blank" rel="noopener noreferrer" class="">v1.1.2 npm-shrinkwrap 解释文档</a>；</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">By default, "npm install" recursively installs the target's dependencies (as specified in package.json), choosing the latest available version that satisfies the dependency's semver pattern.</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">When "npm install" installs a package with a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than package.json files) completely drives the installation of that package and all of its dependencies (recursively). </span><br></div></code></pre></div></div>
<p>使用方法</p>
<ol>
<li class="">npm i 递归安装package.json 中记载的依赖，依赖版本选择符合 semver 版本的最新版。</li>
<li class="">通过 npm shrinkwrap 生成 npm-shrinkwrap.json 文件来保存当前依赖的版本信息</li>
<li class="">当 npm-shrinkwrap.json 文件存在时,按照此文件中记载的依赖版本，进行安装</li>
</ol>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[Nodejs Process 信号事件]]></title>
            <link>https://blog.mengfei.tech/blog/nodejs-process-event</link>
            <guid>https://blog.mengfei.tech/blog/nodejs-process-event</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Nodejs Process 信号事件]]></description>
            <content:encoded><![CDATA[<p>当 Node.js 进程收到信号时，则将触发信号事件。 有关标准 POSIX 信号名称（例如 'SIGINT'、'SIGHUP' 等）的列表，请参阅 <a href="https://man7.org/linux/man-pages/man7/signal.7.html" target="_blank" rel="noopener noreferrer" class="">signal(7)</a>。</p>
<p><strong>信号在 Worker 线程上不可用。</strong></p>
<ul>
<li class="">
<p><strong>'SIGINT' 所有平台都支持来自终端的 'SIGINT'，通常可以使用 Ctrl+C 生成（但是这是可配置的）。 当启用终端原始模式并使用 Ctrl+C 时不会生成它。</strong></p>
</li>
<li class="">
<p><strong>'SIGKILL' 不能安装监听器，它会无条件地终止所有平台上的 Node.js。</strong></p>
</li>
<li class="">
<p><strong>发送 SIGINT、SIGTERM、和 SIGKILL 会导致目标进程无条件的终止，之后子进程会报告进程被信号终止。</strong></p>
</li>
<li class="">
<p>'SIGUSR1' 由 Node.js 预留以启动调试器。 可以安装监听器，但这样做可能会干扰调试器。</p>
</li>
<li class="">
<p>'SIGTERM' 和 'SIGINT' 在非 Windows 平台上具有默认的句柄，其在使用代码 128 + signal number 退出之前重置终端模式。 如果这些信号之一安装了监听器，则其默认行为将被删除（Node.js 将不再退出）。</p>
</li>
<li class="">
<p>'SIGPIPE' 默认情况下忽略。 它可以安装监听器。</p>
</li>
<li class="">
<p>'SIGHUP' 在 Windows 上是在关闭控制台窗口时生成，在其他平台上是在各种类似条件下生成。 参见 signal(7)。 它可以安装监听器，但是 Node.js 将在大约 10 秒后被 Windows 无条件地终止。 在非 Windows 平台上，SIGHUP 的默认行为是终止 Node.js，但一旦安装了监听器，则其默认行为将被删除。</p>
</li>
<li class="">
<p>'SIGTERM' Windows 上不支持，可以监听。</p>
</li>
<li class="">
<p>'SIGBREAK' 在 Windows 上，当按下 Ctrl+Break 时会发送。 在非 Windows 平台上，它可以被监听，但无法发送或生成它。</p>
</li>
<li class="">
<p>'SIGWINCH' 当调整控制台大小时会发送。 在 Windows 上，这只会发生在当光标移动时写入控制台，或者当在原始模式下使用可读的终端时。</p>
</li>
<li class="">
<p>'SIGSTOP' 不能安装监听器。</p>
</li>
<li class="">
<p>'SIGBUS'、'SIGFPE'、'SIGSEGV' 和 'SIGILL'，当没有使用 kill(2) 人为引发时，本质上会使进程处于调用 JS 监听器不安全的状态。 这样做可能会导致进程停止响应。</p>
</li>
<li class="">
<p>0 可以发送来测试进程是否存在，如果进程存在则没影响，如果进程不存在则抛出错误。
Windows 不支持信号，因此没有等价的使用信号来终止，但 Node.js 提供了一些对 process.kill() 和 subprocess.kill() 的模拟：</p>
</li>
<li class="">
<p>发送信号 0 可以作为独立于平台的方式来测试进程是否存在。</p>
</li>
</ul>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[前端自动化测试]]></title>
            <link>https://blog.mengfei.tech/blog/fe-autest</link>
            <guid>https://blog.mengfei.tech/blog/fe-autest</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[前端自动化测试]]></description>
            <content:encoded><![CDATA[<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/fe-autest#%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95" class="">前端自动化测试</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/fe-autest#%E5%89%8D%E8%A8%80" class="">前言</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/fe-autest#%E6%B5%8B%E8%AF%95%E6%A1%86%E6%9E%B6" class="">测试框架</a></li>
</ul>
</li>
</ul>
<p>在公司开始尝试推行编写前端测试用例</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="前言">前言<a href="https://blog.mengfei.tech/blog/fe-autest#%E5%89%8D%E8%A8%80" class="hash-link" aria-label="Direct link to 前言" title="Direct link to 前言" translate="no">​</a></h2>
<p>测试种类繁多，但测试的最终目的，无外乎保从各个环节障程序的健壮，稳定。</p>
<p>// 目录:/assets/share03/软件测试.xmind</p>
<ul>
<li class="">
<p>单元测试</p>
<ul>
<li class="">前端测试粒度常见以函数，类，组件，模块等为单位，编写测试代码。(当前项目环境中欠缺)</li>
</ul>
</li>
<li class="">
<p>集成测试</p>
<ul>
<li class="">多模块联合起来是否符合功能预期的测试。(目前主要依赖测试人员的手工测试,脚本测试)</li>
</ul>
</li>
<li class="">
<p>系统测试</p>
<ul>
<li class="">通常用黑盒的方式进行，包括健壮性测试，性能测试，功能测试，用户界面测试，压力测试等。在不断的需求变更后，进行回归测试，保证程序的可用性。（类比我们 stage 上的回归测试）</li>
</ul>
</li>
<li class="">
<p>验收测试</p>
<ul>
<li class="">内测(alpha， 可以类比我们的 A 环境测试)，公测(beta，可以类比我们的 B 环境测试)。</li>
</ul>
<p>// 目录: /assets/share01/React 前端测试.xmind</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="测试框架">测试框架<a href="https://blog.mengfei.tech/blog/fe-autest#%E6%B5%8B%E8%AF%95%E6%A1%86%E6%9E%B6" class="hash-link" aria-label="Direct link to 测试框架" title="Direct link to 测试框架" translate="no">​</a></h2>
<ul>
<li class="">jest<!-- -->
<ul>
<li class="">github <a href="https://github.com/facebook/jest" target="_blank" rel="noopener noreferrer" class="">https://github.com/facebook/jest</a></li>
<li class="">英文 <a href="https://jestjs.io/" target="_blank" rel="noopener noreferrer" class="">https://jestjs.io/</a></li>
<li class="">中文 <a href="https://www.jestjs.cn/" target="_blank" rel="noopener noreferrer" class="">https://www.jestjs.cn/</a></li>
</ul>
</li>
<li class="">cypress<!-- -->
<ul>
<li class="">github <a href="https://github.com/cypress-io/cypress" target="_blank" rel="noopener noreferrer" class="">https://github.com/cypress-io/cypress</a></li>
<li class="">英文 <a href="https://www.cypress.io/" target="_blank" rel="noopener noreferrer" class="">https://www.cypress.io/</a></li>
</ul>
</li>
</ul>]]></content:encoded>
            <category>testing</category>
        </item>
        <item>
            <title><![CDATA[Github快速接入github action]]></title>
            <link>https://blog.mengfei.tech/blog/github-actions</link>
            <guid>https://blog.mengfei.tech/blog/github-actions</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Github快速接入github action]]></description>
            <category>github</category>
        </item>
        <item>
            <title><![CDATA[Github快速接入travis]]></title>
            <link>https://blog.mengfei.tech/blog/github-travis</link>
            <guid>https://blog.mengfei.tech/blog/github-travis</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Github快速接入travis]]></description>
            <category>github</category>
        </item>
        <item>
            <title><![CDATA[前端常用命令速查备忘]]></title>
            <link>https://blog.mengfei.tech/blog/quick-look</link>
            <guid>https://blog.mengfei.tech/blog/quick-look</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[前端常用命令速查备忘]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="npm--yarn">npm &amp; yarn<a href="https://blog.mengfei.tech/blog/quick-look#npm--yarn" class="hash-link" aria-label="Direct link to npm &amp; yarn" title="Direct link to npm &amp; yarn" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt;  #查看远端仓库 pkg 包信息, 后面可跟 package.json 中字段查看具体信息</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; version  # 当前版本</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; versions  # 版本列表</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; engines  # 依赖的 node版本，或npm 版本， yarn 版本等等</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; dependencies  </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; devDependencies  </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn info &lt;pkg&gt; peerDependencies  </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn why &lt;pkg&gt; # 查看项目有没有包 pkg, 会列出包版本和被谁依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">yarn </span><br></div></code></pre></div></div>]]></content:encoded>
            <category>nodejs</category>
        </item>
        <item>
            <title><![CDATA[ReactHooks]]></title>
            <link>https://blog.mengfei.tech/blog/react-hooks</link>
            <guid>https://blog.mengfei.tech/blog/react-hooks</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[ReactHooks]]></description>
            <content:encoded><![CDATA[<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#%E5%9F%BA%E7%A1%80-hooks" class="">基础 hooks</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usestate" class="">useState</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#useeffect" class="">useEffect</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usecontext" class="">useContext</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#%E5%85%B6%E4%BB%96-hooks" class="">其他 hooks</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usereducer" class="">useReducer</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usecallback" class="">useCallback</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usememo" class="">useMemo</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#useref" class="">useRef</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#useimperativehandle" class="">useImperativeHandle</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#uselayouteffect" class="">useLayoutEffect</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/react-hooks#usedebugvalue" class="">useDebugValue</a></li>
</ul>
</li>
</ul>
<blockquote>
<p>React 16.8 加入的特性。 React hooks 允许开发者，在函数组件中，使用 state,和类似生命周期的功能。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="基础-hooks">基础 hooks<a href="https://blog.mengfei.tech/blog/react-hooks#%E5%9F%BA%E7%A1%80-hooks" class="hash-link" aria-label="Direct link to 基础 hooks" title="Direct link to 基础 hooks" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usestate">useState<a href="https://blog.mengfei.tech/blog/react-hooks#usestate" class="hash-link" aria-label="Direct link to useState" title="Direct link to useState" translate="no">​</a></h3>
<p>概述：用来声明状态，和改变该状态的函数。</p>
<p>参数：状态初始值，或者一个返回初始值的函数。只会在组件出初次渲染时执行。</p>
<p>用法：</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">const [state, setState] = useState(initialState); // 参考Es6 数组的结构赋值</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">const [state, setState] = useState(() =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   const initialState = someExpensiveComputation(props);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   return initialState;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">});</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>eg：</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">function Counter({initialCount}) {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  const [count, setCount] = useState(initialCount);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  return (</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    &lt;&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      Count: {count}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      &lt;button onClick={() =&gt; setCount(0)}&gt;Reset&lt;/button&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      &lt;button onClick={() =&gt; setCount(prevCount =&gt; prevCount + 1)}&gt;+&lt;/button&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      &lt;button onClick={() =&gt; setCount(prevCount =&gt; prevCount - 1)}&gt;-&lt;/button&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    &lt;/&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  );</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="useeffect">useEffect<a href="https://blog.mengfei.tech/blog/react-hooks#useeffect" class="hash-link" aria-label="Direct link to useEffect" title="Direct link to useEffect" translate="no">​</a></h3>
<p>概述：处理具有副作用的行为，例如（订阅，计时器，日志记录等。），并在函数组件渲染结束后运行。</p>
<p>参数：</p>
<ol>
<li class="">第一个参数，接收一个可能具有副作用（订阅，计时器，日志记录等。）的函数。该函数的返回值，可能是一个清理函数。</li>
<li class="">第二个参数（可选），含有执行依赖的数组。当该参数为空数组时，该 effects 只在初次渲染后执行。</li>
</ol>
<p>用法：</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">useEffect(</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    const subscription = props.source.subscribe();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    return () =&gt; { // 组件被移除前执行清理函数</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      subscription.unsubscribe();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    };</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  [props.source], // 依赖改变，订阅函数才会执行</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">useEffect(</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    const subscription = props.source.subscribe();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    return () =&gt; { // 组件被移除前执行清理函数</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      subscription.unsubscribe();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    };</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  [], // 初次渲染 执行</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">);</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usecontext">useContext<a href="https://blog.mengfei.tech/blog/react-hooks#usecontext" class="hash-link" aria-label="Direct link to useContext" title="Direct link to useContext" translate="no">​</a></h3>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">const MyContext = React.createContext(defaultValue);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">const value = useContext(MyContext);</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="其他-hooks">其他 hooks<a href="https://blog.mengfei.tech/blog/react-hooks#%E5%85%B6%E4%BB%96-hooks" class="hash-link" aria-label="Direct link to 其他 hooks" title="Direct link to 其他 hooks" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usereducer">useReducer<a href="https://blog.mengfei.tech/blog/react-hooks#usereducer" class="hash-link" aria-label="Direct link to useReducer" title="Direct link to useReducer" translate="no">​</a></h3>
<p>概述：在状态较复杂时使用.我的理解是，和 redux 类似的概念。因为工作一直在 使用 redux。所以这个概念，暂时不做深入了解。以后有机会用到的话，再深入学习。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usecallback">useCallback<a href="https://blog.mengfei.tech/blog/react-hooks#usecallback" class="hash-link" aria-label="Direct link to useCallback" title="Direct link to useCallback" translate="no">​</a></h3>
<p>概述：类似 useMemo，返回一个 callback 函数，</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">const memoizedCallback = useCallback(</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    doSomething(a, b);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  [a, b],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">);</span><br></div></code></pre></div></div>
<ul>
<li class="">测试中，遇到问题：依赖值没变，但会重新进行计算。</li>
<li class="">有点没搞懂，这个 hook 的使用场景</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usememo">useMemo<a href="https://blog.mengfei.tech/blog/react-hooks#usememo" class="hash-link" aria-label="Direct link to useMemo" title="Direct link to useMemo" translate="no">​</a></h3>
<p>概述：返回一个计算值，只在依赖发生变化时计算。</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">const memoizedValue = useMemo(() =&gt; computeExpensiveValue(a, b), [a, b]);</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="useref">useRef<a href="https://blog.mengfei.tech/blog/react-hooks#useref" class="hash-link" aria-label="Direct link to useRef" title="Direct link to useRef" translate="no">​</a></h3>
<p>概述：useRef 返回一个可变的 ref 对象。初始化时，初始化参数将被赋值给该对象的 current 属性。这个 ref 对象，存在在整个组件的生命周期内</p>
<p>最常用的用法，是用 ref 对象存储一个 dom 对象。eg:</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">function TextInputWithFocusButton() {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  const inputEl = useRef(null);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  const onButtonClick = () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    // `current` points to the mounted text input element</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    inputEl.current.focus();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  };</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  return (</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    &lt;&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      &lt;input ref={inputEl} type="text" /&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      &lt;button onClick={onButtonClick}&gt;Focus the input&lt;/button&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    &lt;/&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  );</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>但是，ref 对象并不是只能存储 dom 对象。它是一个通用容器。有些类似 类的实例属性。可以存储任意类型的值。eg:</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">function Timer() {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  const intervalRef = useRef();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  useEffect(() =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    const id = setInterval(() =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      // ...</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    });</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    intervalRef.current = id;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    return () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      clearInterval(intervalRef.current);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    };</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  });</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  // ...</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="useimperativehandle">useImperativeHandle<a href="https://blog.mengfei.tech/blog/react-hooks#useimperativehandle" class="hash-link" aria-label="Direct link to useImperativeHandle" title="Direct link to useImperativeHandle" translate="no">​</a></h3>
<p>概述：在使用 ref 时，可以使用 useImperativeHandle，选择特定的实例属性暴漏给父组件。</p>
<p>必须结合 forwardRef 使用</p>
<div class="language-react codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-react codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">function FancyInput(props, ref) {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  const inputRef = useRef();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  useImperativeHandle(ref, () =&gt; ({</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    focus: () =&gt; {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      inputRef.current.focus();</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  }));</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  return &lt;input ref={inputRef} ... /&gt;;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">FancyInput = forwardRef(FancyInput);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">// 在父组件中拿到的ref引用，是一个 { focus:Function } 的对象。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="uselayouteffect">useLayoutEffect<a href="https://blog.mengfei.tech/blog/react-hooks#uselayouteffect" class="hash-link" aria-label="Direct link to useLayoutEffect" title="Direct link to useLayoutEffect" translate="no">​</a></h3>
<p>与 useEffect 类似，</p>
<p>useLayoutEffect 在 componentDidMount 和 componentDidUpdate 相同的阶段触发。</p>
<p>React 官方建议，优先使用 useEffect，只在使用 useEffect 遇到问题时，尝试使用 useLayoutEffect</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usedebugvalue">useDebugValue<a href="https://blog.mengfei.tech/blog/react-hooks#usedebugvalue" class="hash-link" aria-label="Direct link to useDebugValue" title="Direct link to useDebugValue" translate="no">​</a></h3>]]></content:encoded>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[Typescript使用总结及部分小技巧]]></title>
            <link>https://blog.mengfei.tech/blog/ts-usage-summary</link>
            <guid>https://blog.mengfei.tech/blog/ts-usage-summary</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[Typescript使用总结及部分小技巧]]></description>
            <content:encoded><![CDATA[<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#typescript-%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93%E5%8F%8A%E9%83%A8%E5%88%86%E5%B0%8F%E6%8A%80%E5%B7%A7" class="">Typescript 使用总结及部分小技巧</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#1-typescript-%E9%83%A8%E5%88%86%E5%B8%B8%E7%94%A8%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%A2%AB%E5%BF%BD%E7%95%A5%E7%9A%84%E7%9F%A5%E8%AF%86%E7%82%B9" class="">1. Typescript 部分常用可能会被忽略的知识点</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#11-%E7%B1%BB%E5%9E%8B%E8%8E%B7%E5%8F%96" class="">1.1 类型获取</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#111-typeof" class="">1.1.1 typeof</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#112-%E7%B4%A2%E5%BC%95%E7%B1%BB%E5%9E%8B%E6%9F%A5%E8%AF%A2%E6%93%8D%E4%BD%9C%E7%AC%A6-keyof" class="">1.1.2 索引类型查询操作符 keyof</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#113-%E7%B4%A2%E5%BC%95%E8%AE%BF%E9%97%AE" class="">1.1.3 索引访问</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#12-%E6%B3%9B%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%92%8C%E5%AE%9A%E4%B9%89" class="">1.2 泛型的使用和定义</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#13-%E6%9D%A1%E4%BB%B6%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%92%8C%E5%AE%9A%E4%B9%89" class="">1.3 条件类型的使用和定义</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#2-react-%E9%A1%B9%E7%9B%AE%E4%B8%AD%E7%9A%84-typescript" class="">2. React 项目中的 Typescript</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#21-%E8%87%AA%E5%AE%9A%E4%BF%AE%E5%A4%8D%E5%92%8C%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5" class="">2.1 自定修复和自动导入</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#211-%E4%B9%A6%E5%86%99%E6%97%B6%E7%9A%84%E6%99%BA%E8%83%BD%E6%8F%90%E7%A4%BA%E5%92%8C%E5%AF%BC%E5%85%A5" class="">2.1.1 书写时的智能提示和导入</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#212-%E8%87%AA%E5%8A%A8-fix-%E7%9A%84%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5" class="">2.1.2 自动 fix 的自动导入</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#22-%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-props-%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B" class="">2.2 定义组件的 props 中的类型</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#221-props-%E7%9A%84-interface-%E5%AE%9A%E4%B9%89%E4%BD%8D%E7%BD%AE" class="">2.2.1 props 的 interface 定义位置</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#222-%E5%AF%BC%E5%87%BA%E5%8F%AF%E8%83%BD%E4%BC%9A%E7%94%A8%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8Binterfacetypeenum" class="">2.2.2 导出可能会用到的类型（interface/type/enum）</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#223-%E4%BD%BF%E7%94%A8%E5%92%8C%E6%9F%A5%E6%89%BE%E5%B7%B2%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B" class="">2.2.3 使用和查找已定义的类型</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#23-%E4%BC%A0%E9%80%92%E7%BB%84%E4%BB%B6-props-%E6%97%B6%E4%BD%BF%E7%94%A8%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8B" class="">2.3 传递组件 props 时，使用到的类型</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#24-vsocde-%E4%B8%AD%E7%9A%84%E9%87%8D%E6%9E%84" class="">2.4 Vsocde 中的重构</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#241-%E5%BC%95%E7%94%A8%E6%9F%A5%E6%89%BE" class="">2.4.1 引用查找</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#242-%E5%BC%95%E7%94%A8%E9%87%8D%E5%91%BD%E5%90%8D" class="">2.4.2 引用重命名</a></li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#25-%E4%BD%BF%E7%94%A8-code-snippets" class="">2.5 使用 code snippets</a>
<ul>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#241-es7-reactreduxreact-nativejs-snippets" class="">2.4.1 ES7 React/Redux/React-Native/JS snippets</a></li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#242-typescript-react-code-snippets" class="">2.4.2 Typescript React Code snippets</a></li>
</ul>
</li>
</ul>
</li>
<li class=""><a href="https://blog.mengfei.tech/blog/ts-usage-summary#3-react-redux-%E7%BB%93%E5%90%88-typescript" class="">3 React Redux 结合 Typescript</a></li>
</ul>
</li>
</ul>
<p>备份一篇去年写的关于ts 使用的小文章。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-typescript-部分常用可能会被忽略的知识点">1. Typescript 部分常用可能会被忽略的知识点<a href="https://blog.mengfei.tech/blog/ts-usage-summary#1-typescript-%E9%83%A8%E5%88%86%E5%B8%B8%E7%94%A8%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%A2%AB%E5%BF%BD%E7%95%A5%E7%9A%84%E7%9F%A5%E8%AF%86%E7%82%B9" class="hash-link" aria-label="Direct link to 1. Typescript 部分常用可能会被忽略的知识点" title="Direct link to 1. Typescript 部分常用可能会被忽略的知识点" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="11-类型获取">1.1 类型获取<a href="https://blog.mengfei.tech/blog/ts-usage-summary#11-%E7%B1%BB%E5%9E%8B%E8%8E%B7%E5%8F%96" class="hash-link" aria-label="Direct link to 1.1 类型获取" title="Direct link to 1.1 类型获取" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="111-typeof">1.1.1 typeof<a href="https://blog.mengfei.tech/blog/ts-usage-summary#111-typeof" class="hash-link" aria-label="Direct link to 1.1.1 typeof" title="Direct link to 1.1.1 typeof" translate="no">​</a></h4>
<p>使用 typeof 获取变量类型</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div 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">Setting</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">color</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"red"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">font</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"xxx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><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">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><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">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div 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"> </span><span class="token string" style="color:#e3116c">"xxxx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">type </span><span class="token maybe-class-name">SettingType</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">typeof</span><span class="token plain"> </span><span class="token maybe-class-name">Setting</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">getPropX</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></div><div 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">"xxx"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">type </span><span class="token maybe-class-name">GetPropXType</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">typeof</span><span class="token plain"> getPropX</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">type </span><span class="token maybe-class-name">GetPropXReturnType</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">ReturnType</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> getPropX</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="112-索引类型查询操作符-keyof">1.1.2 索引类型查询操作符 keyof<a href="https://blog.mengfei.tech/blog/ts-usage-summary#112-%E7%B4%A2%E5%BC%95%E7%B1%BB%E5%9E%8B%E6%9F%A5%E8%AF%A2%E6%93%8D%E4%BD%9C%E7%AC%A6-keyof" class="hash-link" aria-label="Direct link to 1.1.2 索引类型查询操作符 keyof" title="Direct link to 1.1.2 索引类型查询操作符 keyof" translate="no">​</a></h4>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> Setting </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></div><div class="token-line" style="color:#393A34"><span class="token plain">  color</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"red"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  font</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"xxx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  width</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 punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  height</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 punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"xxxx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// type SettingKey = 'color' | 'font' | 'width' | 'height' | 'title'</span><span class="token plain"></span><br></div><div 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">SettingKey</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">keyof</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> Setting</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="113-索引访问">1.1.3 索引访问<a href="https://blog.mengfei.tech/blog/ts-usage-summary#113-%E7%B4%A2%E5%BC%95%E8%AE%BF%E9%97%AE" class="hash-link" aria-label="Direct link to 1.1.3 索引访问" title="Direct link to 1.1.3 索引访问" translate="no">​</a></h4>
<p>使用 <code>typeName['propName']</code> 格式读取属性类型</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">interface</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div 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 punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  age</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  sex</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"man"</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">"woman"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  job</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function-variable function" style="color:#d73a49">eat</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">food</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 keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">eat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Person</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"eat"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="12-泛型的使用和定义">1.2 泛型的使用和定义<a href="https://blog.mengfei.tech/blog/ts-usage-summary#12-%E6%B3%9B%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%92%8C%E5%AE%9A%E4%B9%89" class="hash-link" aria-label="Direct link to 1.2 泛型的使用和定义" title="Direct link to 1.2 泛型的使用和定义" translate="no">​</a></h3>
<blockquote>
<p>泛型其实就是类型变量，根据传入的类型，获取到需要的类型</p>
</blockquote>
<p>添加泛型的位置:</p>
<ul>
<li class="">函数泛型 -- 在函数上添加泛型</li>
</ul>
<p><img decoding="async" loading="lazy" alt="auto import" src="https://blog.mengfei.tech/assets/images/3-2672314d63e71850a8ca080dab061316.png" width="866" height="230" class="img_ev3q"></p>
<ul>
<li class="">类泛型 -- 在类上添加泛型</li>
</ul>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">GenericNumber</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name constant" style="color:#36acaa">T</span><span class="token class-name 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></div><div class="token-line" style="color:#393A34"><span class="token plain">  zeroValue</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function-variable function" style="color:#d73a49">add</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">x</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"> y</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 constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<ul>
<li class="">类型泛型 -- 在接口或类型别名(使用 type 或 interface 定义的类型)上添加泛型</li>
</ul>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// antd rowSelection 的类型</span><span class="token plain"></span><br></div><div 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">TableRowSelection</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name constant" style="color:#36acaa">T</span><span class="token class-name 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></div><div class="token-line" style="color:#393A34"><span class="token plain">  type</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> RowSelectionType</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  selectedRowKeys</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" 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 punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  onChange</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">selectedRowKeys</span><span class="token operator" 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 punctuation" style="color:#393A34">,</span><span class="token plain"> selectedRows</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 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 keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  getCheckboxProps</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">record</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"> Partial</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">Omit</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">CheckboxProps</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"checked"</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">"defaultChecked"</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  onSelect</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> SelectionSelectFn</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  onSelectMultiple</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">selected</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">boolean</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> selectedRows</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 punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> changeRows</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 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 keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/** </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@deprecated</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> This function is meaningless and should use `onChange` instead */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  onSelectAll</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">selected</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">boolean</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> selectedRows</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 punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> changeRows</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 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 keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/** </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@deprecated</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> This function is meaningless and should use `onChange` instead */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  onSelectInvert</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">selectedRowKeys</span><span class="token operator" 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 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></div><div class="token-line" style="color:#393A34"><span class="token plain">  selections</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 constant" style="color:#36acaa">INTERNAL_SELECTION_ITEM</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 builtin">boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  hideDefaultSelections</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">boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  fixed</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">boolean</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  columnWidth</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 plain"> </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></div><div class="token-line" style="color:#393A34"><span class="token plain">  columnTitle</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 plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ReactNode</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  renderCell</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></div><div class="token-line" style="color:#393A34"><span class="token plain">    value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">boolean</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    record</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></div><div class="token-line" style="color:#393A34"><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><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    originNode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ReactNode</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div 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"> React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ReactNode </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> RcRenderedCell</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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// antd table columns 的类型</span><span class="token plain"></span><br></div><div 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">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">ColumnsType</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name">RecordType </span><span class="token class-name operator" style="color:#393A34">=</span><span class="token class-name"> </span><span class="token class-name builtin">unknown</span><span class="token class-name operator" style="color:#393A34">&gt;</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> ColumnGroupType</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">RecordType</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> ColumnType</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">RecordType</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div 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 punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="13-条件类型的使用和定义">1.3 条件类型的使用和定义<a href="https://blog.mengfei.tech/blog/ts-usage-summary#13-%E6%9D%A1%E4%BB%B6%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%92%8C%E5%AE%9A%E4%B9%89" class="hash-link" aria-label="Direct link to 1.3 条件类型的使用和定义" title="Direct link to 1.3 条件类型的使用和定义" translate="no">​</a></h3>
<p>常用的条件类型</p>
<blockquote>
<p>更过预定义的条件类型 typescript/lib/lib.d.ts</p>
</blockquote>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">- Partial&lt;T&gt; -- 使 T 中的所有属性变成可选属性</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Pick&lt;T,K extends keyof T&gt; -- 从 T 中挑选属性 K，组成新的类型</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Omit&lt;T, K extends keyof any&gt; -- 从 T 中删除属性 K，组成新的类型</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- ReturnType&lt;T extends (...args: any) =&gt; any&gt; -- 获取函数的返回值类型</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Required&lt;T&gt; -- 使 T 中的所有属性变成必选属性</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Readonly&lt;T&gt; -- 使 T 中的所有属性变成只读属性</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Exclude&lt;T, U&gt; -- 从 T 中剔除可以赋值给 U 的类型。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- Extract&lt;T, U&gt; -- 提取 T 中可以赋值给 U 的类型。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- NonNullable&lt;T&gt; -- 从 T 中剔除 null 和 undefined。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- ReturnType&lt;T&gt; -- 获取函数返回值类型。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">- InstanceType&lt;T&gt; -- 获取构造函数类型的实例类型。</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-react-项目中的-typescript">2. React 项目中的 Typescript<a href="https://blog.mengfei.tech/blog/ts-usage-summary#2-react-%E9%A1%B9%E7%9B%AE%E4%B8%AD%E7%9A%84-typescript" class="hash-link" aria-label="Direct link to 2. React 项目中的 Typescript" title="Direct link to 2. React 项目中的 Typescript" translate="no">​</a></h2>
<p>此章节重点,类型定义和类型使用经验和小技巧</p>
<blockquote>
<ol>
<li class="">使用 vscode 开发 typescript 时，强大的智能提示和自动导入以及自动修复功能的使用。</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li class="">类型的复用</li>
</ol>
</blockquote>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="21-自定修复和自动导入">2.1 自定修复和自动导入<a href="https://blog.mengfei.tech/blog/ts-usage-summary#21-%E8%87%AA%E5%AE%9A%E4%BF%AE%E5%A4%8D%E5%92%8C%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5" class="hash-link" aria-label="Direct link to 2.1 自定修复和自动导入" title="Direct link to 2.1 自定修复和自动导入" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="211-书写时的智能提示和导入">2.1.1 书写时的智能提示和导入<a href="https://blog.mengfei.tech/blog/ts-usage-summary#211-%E4%B9%A6%E5%86%99%E6%97%B6%E7%9A%84%E6%99%BA%E8%83%BD%E6%8F%90%E7%A4%BA%E5%92%8C%E5%AF%BC%E5%85%A5" class="hash-link" aria-label="Direct link to 2.1.1 书写时的智能提示和导入" title="Direct link to 2.1.1 书写时的智能提示和导入" translate="no">​</a></h4>
<p>跨文件，可导入的 类型 / 方法 / 变量 ...的智能提示，以及自动导入</p>
<p><img decoding="async" loading="lazy" alt="auto import" src="https://blog.mengfei.tech/assets/images/1-6219a770f848a2930a598ce3afc03830.gif" width="716" height="267" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="212-自动-fix-的自动导入">2.1.2 自动 fix 的自动导入<a href="https://blog.mengfei.tech/blog/ts-usage-summary#212-%E8%87%AA%E5%8A%A8-fix-%E7%9A%84%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5" class="hash-link" aria-label="Direct link to 2.1.2 自动 fix 的自动导入" title="Direct link to 2.1.2 自动 fix 的自动导入" translate="no">​</a></h4>
<p>单个修复导入 <img decoding="async" loading="lazy" alt="fix import" src="https://blog.mengfei.tech/assets/images/2-791a492f78e5c8e685359eec597afad1.gif" width="761" height="206" class="img_ev3q"></p>
<p>所有修复导入 <img decoding="async" loading="lazy" alt="fix import all" src="https://blog.mengfei.tech/assets/images/3-cd7969c057c3718ccb887b3f37f4f8d0.gif" width="761" height="206" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="22-定义组件的-props-中的类型">2.2 定义组件的 props 中的类型<a href="https://blog.mengfei.tech/blog/ts-usage-summary#22-%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-props-%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="Direct link to 2.2 定义组件的 props 中的类型" title="Direct link to 2.2 定义组件的 props 中的类型" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="221-props-的-interface-定义位置">2.2.1 props 的 interface 定义位置<a href="https://blog.mengfei.tech/blog/ts-usage-summary#221-props-%E7%9A%84-interface-%E5%AE%9A%E4%B9%89%E4%BD%8D%E7%BD%AE" class="hash-link" aria-label="Direct link to 2.2.1 props 的 interface 定义位置" title="Direct link to 2.2.1 props 的 interface 定义位置" translate="no">​</a></h4>
<blockquote>
<p>props 的 interface 定义位置: 组件文件中</p>
</blockquote>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" 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"> </span><span class="token imports maybe-class-name">React</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">"react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">IComNameProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 maybe-class-name">ComName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">FunctionComponent</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">IComNameProps</span><span class="token operator" style="color:#393A34">&gt;</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">props</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></div><div 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 tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">ComName</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">default</span><span class="token plain"> </span><span class="token maybe-class-name">ComName</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="222-导出可能会用到的类型interfacetypeenum">2.2.2 导出可能会用到的类型（interface/type/enum）<a href="https://blog.mengfei.tech/blog/ts-usage-summary#222-%E5%AF%BC%E5%87%BA%E5%8F%AF%E8%83%BD%E4%BC%9A%E7%94%A8%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8Binterfacetypeenum" class="hash-link" aria-label="Direct link to 2.2.2 导出可能会用到的类型（interface/type/enum）" title="Direct link to 2.2.2 导出可能会用到的类型（interface/type/enum）" translate="no">​</a></h4>
<blockquote>
<p>大部分组件的 props 的 interface, 可以使用 export 导出,方便在使用组件时，部分类型的使用(可以参考下一章节:<a href="https://blog.mengfei.tech/blog/ts-usage-summary#%E4%BC%A0%E9%80%92%E7%BB%84%E4%BB%B6-props-%E6%97%B6%E4%BD%BF%E7%94%A8%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8B" class="">传递组件 props 时，使用到的类型</a>)。</p>
</blockquote>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div 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">interface</span><span class="token plain"> </span><span class="token class-name">IComNameProps</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="223-使用和查找已定义的类型">2.2.3 使用和查找已定义的类型<a href="https://blog.mengfei.tech/blog/ts-usage-summary#223-%E4%BD%BF%E7%94%A8%E5%92%8C%E6%9F%A5%E6%89%BE%E5%B7%B2%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="Direct link to 2.2.3 使用和查找已定义的类型" title="Direct link to 2.2.3 使用和查找已定义的类型" translate="no">​</a></h4>
<blockquote>
<p>定义组件 props 属性时，引用类属性，优先考虑使用已定义的类型（善用 vsocde 强大的引用提示，以及自动引入功能）</p>
</blockquote>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" 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">Store</span><span class="token imports"> </span><span class="token imports 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">"antd/lib/form/interface"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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 imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">ResourceSaveDto</span><span class="token imports"> </span><span class="token imports 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">"@/client/services/umgt/resource"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">PopupStore</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">Store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">ResourceSaveDto</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="23-传递组件-props-时使用到的类型">2.3 传递组件 props 时，使用到的类型<a href="https://blog.mengfei.tech/blog/ts-usage-summary#23-%E4%BC%A0%E9%80%92%E7%BB%84%E4%BB%B6-props-%E6%97%B6%E4%BD%BF%E7%94%A8%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="Direct link to 2.3 传递组件 props 时，使用到的类型" title="Direct link to 2.3 传递组件 props 时，使用到的类型" translate="no">​</a></h3>
<blockquote>
<p>上面定义并导出好组件和组件的类型后，在使用此组件时，可同时引入可能用到的类型</p>
</blockquote>
<p>大部分组件的 props 传递时，需要的数据类型，都可以通过鼠标放上去的提示来找到。</p>
<blockquote>
<ol>
<li class="">直接使用和引入单个 props 属性类型</li>
<li class="">引入整个组件 props 类型，使用 interfaceName['propsName]</li>
</ol>
</blockquote>
<p><img decoding="async" loading="lazy" alt="类型查找" src="https://blog.mengfei.tech/assets/images/6-83fdd965fb07dce17877a530a3aa40a9.gif" width="1085" height="583" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="24-vsocde-中的重构">2.4 Vsocde 中的重构<a href="https://blog.mengfei.tech/blog/ts-usage-summary#24-vsocde-%E4%B8%AD%E7%9A%84%E9%87%8D%E6%9E%84" class="hash-link" aria-label="Direct link to 2.4 Vsocde 中的重构" title="Direct link to 2.4 Vsocde 中的重构" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="241-引用查找">2.4.1 引用查找<a href="https://blog.mengfei.tech/blog/ts-usage-summary#241-%E5%BC%95%E7%94%A8%E6%9F%A5%E6%89%BE" class="hash-link" aria-label="Direct link to 2.4.1 引用查找" title="Direct link to 2.4.1 引用查找" translate="no">​</a></h4>
<p><img decoding="async" loading="lazy" alt="引用查找" src="https://blog.mengfei.tech/assets/images/7-e18e63efec7e3ef75b62a90362c58f61.gif" width="1085" height="583" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="242-引用重命名">2.4.2 引用重命名<a href="https://blog.mengfei.tech/blog/ts-usage-summary#242-%E5%BC%95%E7%94%A8%E9%87%8D%E5%91%BD%E5%90%8D" class="hash-link" aria-label="Direct link to 2.4.2 引用重命名" title="Direct link to 2.4.2 引用重命名" translate="no">​</a></h4>
<p>邮件重命名或者 F2 重命名</p>
<p><img decoding="async" loading="lazy" alt="引用查找" src="https://blog.mengfei.tech/assets/images/8-a9f25b0750ba62f4dff63f261f6c33b8.gif" width="1538" height="615" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="25-使用-code-snippets">2.5 使用 code snippets<a href="https://blog.mengfei.tech/blog/ts-usage-summary#25-%E4%BD%BF%E7%94%A8-code-snippets" class="hash-link" aria-label="Direct link to 2.5 使用 code snippets" title="Direct link to 2.5 使用 code snippets" translate="no">​</a></h3>
<p>给大家推荐的 React Ts Extension Pack 包里，包含了两个下载量比较大的 react 语法段的包</p>
<p><img decoding="async" loading="lazy" alt="语法片段包" src="https://blog.mengfei.tech/assets/images/2-42426328eafb13574e46b7c64621c098.png" width="668" height="107" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="241-es7-reactreduxreact-nativejs-snippets">2.4.1 ES7 React/Redux/React-Native/JS snippets<a href="https://blog.mengfei.tech/blog/ts-usage-summary#241-es7-reactreduxreact-nativejs-snippets" class="hash-link" aria-label="Direct link to 2.4.1 ES7 React/Redux/React-Native/JS snippets" title="Direct link to 2.4.1 ES7 React/Redux/React-Native/JS snippets" translate="no">​</a></h4>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">imp→	</span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">moduleName</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">'module'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">imd→	</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"> destructuredModule </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">'module'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">imr→	</span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</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">'react'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">edf→	</span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">params</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><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cp→	</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"> </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 property-access">props</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cs→	</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"> </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 property-access">state</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rcc→</span><br></div><div 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 maybe-class-name">React</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Component</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">'react'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 module" style="color:#00009f">default</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">FileName</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">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">render</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></div><div 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 operator" style="color:#393A34">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">$2</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div 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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rcep→</span><br></div><div 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 maybe-class-name">React</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Component</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">'react'</span><span class="token plain"></span><br></div><div 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 maybe-class-name">PropTypes</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">'prop-types'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">FileName</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">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">static</span><span class="token plain"> propTypes </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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">render</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></div><div 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 operator" style="color:#393A34">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">$2</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div 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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">-</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rafcp→</span><br></div><div 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 maybe-class-name">React</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">'react'</span><span class="token plain"></span><br></div><div 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 maybe-class-name">PropTypes</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">'prop-types'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">$1</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 parameter">props</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></div><div 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 operator" style="color:#393A34">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">$0</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">$1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">propTypes</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><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 module" style="color:#00009f">default</span><span class="token plain"> $1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 module" style="color:#00009f">default</span><span class="token plain"> $1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">-</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rcredux→</span><br></div><div 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 maybe-class-name">React</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Component</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">'react'</span><span class="token plain"></span><br></div><div 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"> connect </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">'react-redux'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">FileName</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">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">render</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></div><div 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 operator" style="color:#393A34">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">$4</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div 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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">mapStateToProps</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 parameter">state</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 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mapDispatchToProps </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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">connect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mapStateToProps</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> mapDispatchToProps</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">FileName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="242-typescript-react-code-snippets">2.4.2 Typescript React Code snippets<a href="https://blog.mengfei.tech/blog/ts-usage-summary#242-typescript-react-code-snippets" class="hash-link" aria-label="Direct link to 2.4.2 Typescript React Code snippets" title="Direct link to 2.4.2 Typescript React Code snippets" translate="no">​</a></h4>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// tsrsfc	stateless functional component</span><span class="token plain"></span><br></div><div 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 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"> </span><span class="token imports maybe-class-name">React</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">"react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">IAppProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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 maybe-class-name">App</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">FunctionComponent</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">IAppProps</span><span class="token operator" style="color:#393A34">&gt;</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">props</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 punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">default</span><span class="token plain"> </span><span class="token maybe-class-name">App</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">-</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// tsrcc→	class component skeleton</span><span class="token plain"></span><br></div><div 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 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"> </span><span class="token imports maybe-class-name">React</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">"react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">IAppProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">default</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">App</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">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">Component</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">IAppProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">render</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></div><div 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 tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">--</span><span class="token operator" style="color:#393A34">-</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// tscntr→	react redux container skeleton</span><span class="token plain"></span><br></div><div 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 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"> </span><span class="token imports maybe-class-name">React</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">"react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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 imports punctuation" style="color:#393A34">{</span><span class="token imports"> connect </span><span class="token imports 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">"react-redux"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">IAppProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">App</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">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">Component</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">IAppProps</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></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">render</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></div><div 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 tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">mapState2Props</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">state</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></div><div 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 punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div 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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div 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">default</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">connect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mapState2Props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-react-redux-结合-typescript">3 React Redux 结合 Typescript<a href="https://blog.mengfei.tech/blog/ts-usage-summary#3-react-redux-%E7%BB%93%E5%90%88-typescript" class="hash-link" aria-label="Direct link to 3 React Redux 结合 Typescript" title="Direct link to 3 React Redux 结合 Typescript" translate="no">​</a></h2>
<p><a href="https://redux.js.org/recipes/usage-with-typescript#type-checking-state" target="_blank" rel="noopener noreferrer" class="">Redux Typescript 基础写法</a></p>]]></content:encoded>
            <category>typescript</category>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[如何在JS文件里写类型]]></title>
            <link>https://blog.mengfei.tech/blog/write-ts-in-js</link>
            <guid>https://blog.mengfei.tech/blog/write-ts-in-js</guid>
            <pubDate>Mon, 19 Oct 2026 10:36:32 GMT</pubDate>
            <description><![CDATA[如何在JS文件里写类型]]></description>
            <content:encoded><![CDATA[<p>很多同学在刚开始学习写ts的时候，不太清楚如何写类型，以及何时应该写类型，又该何时使用类型。
这里引出了三个问题：</p>
<ol>
<li class="">如何定义类型</li>
<li class="">何时定义类型<!-- -->
<ol>
<li class="">数据产生，和数据获取的地方。</li>
<li class="">比如定义请求函数的地方， 独立组件props的定义，都是经典且基础的需要定义类型的地方</li>
</ol>
</li>
<li class="">何时使用类型，即引用类型<!-- -->
<ol>
<li class="">数据使用的地方，数据关联的地方，这些地方，应该优先引用上述定义的类型，而无需重复定义类型。</li>
<li class="">例如使用请求来的数据的时候，使用请求函数定义时定义的类型</li>
<li class="">组件使用的时候，使用组件定义时定义的类型。</li>
<li class="">数据关联的地方，指比如两个接口，获取的数据有一定的包含关系，可以使用类型继承，来引用类型。</li>
</ol>
</li>
</ol>
<p>类型使用和定义，应该遵循，定义尽量少的类型，增加已定义类型的复用性原则。</p>
<p>除了这三个问题外，还有一个练习太少的问题，很多老的项目，并没有使用Ts 编写。那么除了自己的ts 练习项目外，
还可以在哪里熟悉 ts类型的写法呢。</p>
<p>这里向大家介绍一个可能很多人都见过，并且写过的东西， ------------------- JSDOC。
我们可以使用JSDOC, 定义各种类型，以及可以被vscode良好的支持，给出边界的类型代码提示。</p>
<p>下面这种注释，估计大部分前端开发者都见过，并且都写过，但可能了解的并不是很多。下面我们对JSDOC是什么，
以及有什么作用来做个介绍</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * 函数Desc</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@param</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">string</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment parameter" style="color:#999988;font-style:italic">params1</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@param</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">number</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment parameter" style="color:#999988;font-style:italic">params2</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><br></div><div 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></div><div 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">name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">params1</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> params2</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></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="jsdoc-介绍">JSDOC 介绍<a href="https://blog.mengfei.tech/blog/write-ts-in-js#jsdoc-%E4%BB%8B%E7%BB%8D" class="hash-link" aria-label="Direct link to JSDOC 介绍" title="Direct link to JSDOC 介绍" translate="no">​</a></h2>
<p>JSDoc是一个根据javascript文件中注释信息，生成JavaScript应用程序或库、模块的API文档 的工具。你可以使用他记录如：命名空间，类，方法，方法参数等。类似JavaDoc和PHPDoc。<strong>现在很多编辑器或IDE中还可以通过JSDoc直接或使用插件生成智能提示。从而使开发者很容易了解整个类和其中的属性和方法，并且快速知道如何使用，从而提高开发效率，降低维护成本。</strong></p>
<p>是标记变量、入参、返回值的类型，稍微弥补了 JavaScript 没有静态类型，不支持类型标注的问题。基于 JSDoc 的类型注释，Google Closure Compiler 可以分析优化代码，<strong>VS Code 之类的代码编辑器可以在不使用 TypeScript 的情况下实现代码提示。</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="历史">历史<a href="https://blog.mengfei.tech/blog/write-ts-in-js#%E5%8E%86%E5%8F%B2" class="hash-link" aria-label="Direct link to 历史" title="Direct link to 历史" translate="no">​</a></h2>
<p>Michael Mathews 在 2001 年创建 JSDoc 项目，它是最早的 JavaScript 文档工具，注释语法借鉴自 Javadoc（很多文档工具都使用了类似 Javadoc 注释语法，比如 C++ 的 Doxygen、 PHP 的 phpDocumentor）。截止 2020 年经历了 4 个大版本更新：</p>
<ul>
<li class="">2001 JSDoc (JSDoc.pm): 使用 Perl 编写，代码托管在 SourceForge</li>
<li class="">2007 JsDoc Toolkit 1.0: 使用 JavaScript 编写，基于 Rhino，运行在 Java 平台，代码托管在 Google Code</li>
<li class="">2008 JsDoc Toolkit 2.0: 同 1.0</li>
<li class="">2011 JSDoc 3: 基于 Node.js，代码托管在 GitHub</li>
</ul>
<p>编译文档用法</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">npm i -g jsdoc </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">jsdoc yourjavascriptfile.js</span><br></div></code></pre></div></div>
<ul>
<li class="">项目地址: <a href="https://github.com/jsdoc/jsdoc" target="_blank" rel="noopener noreferrer" class="">https://github.com/jsdoc/jsdoc</a></li>
<li class="">语法文档: <a href="https://jsdoc.app/" target="_blank" rel="noopener noreferrer" class="">https://jsdoc.app/</a>  <a href="http://www.dba.cn/book/jsdoc/" target="_blank" rel="noopener noreferrer" class="">http://www.dba.cn/book/jsdoc/</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="常用标注">常用标注<a href="https://blog.mengfei.tech/blog/write-ts-in-js#%E5%B8%B8%E7%94%A8%E6%A0%87%E6%B3%A8" class="hash-link" aria-label="Direct link to 常用标注" title="Direct link to 常用标注" translate="no">​</a></h2>
<ul>
<li class="">类型<!-- -->
<ul>
<li class="">@type</li>
<li class="">@typedef</li>
<li class="">@property/@prop</li>
<li class="">@template</li>
<li class="">@enum</li>
</ul>
</li>
<li class="">函数<!-- -->
<ul>
<li class="">@param/@argument/@arg</li>
<li class="">@returns/@return</li>
<li class="">@throws</li>
<li class="">@deprecated</li>
</ul>
</li>
<li class="">类和继承<!-- -->
<ul>
<li class="">@constructor/@class</li>
<li class="">@this</li>
<li class="">@extends</li>
<li class="">@public</li>
<li class="">@private</li>
<li class="">@protected</li>
<li class="">@readonly</li>
</ul>
</li>
<li class="">文档<!-- -->
<ul>
<li class="">@fileoverview</li>
<li class="">@author</li>
<li class="">@example</li>
<li class="">@description</li>
<li class="">@see</li>
<li class="">@link</li>
<li class="">@license</li>
<li class="">@preserve</li>
</ul>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="使用示例">使用示例<a href="https://blog.mengfei.tech/blog/write-ts-in-js#%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="Direct link to 使用示例" title="Direct link to 使用示例" translate="no">​</a></h2>
<p>定义类型：</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * desc desc desc</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@typedef</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">string</span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">|</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">number</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">TypeName</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * /</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * desc desc desc</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@typedef</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">Object</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">ObjectTypeName</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@property</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">string</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment parameter" style="color:#999988;font-style:italic">name</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@property</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">number</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment parameter" style="color:#999988;font-style:italic">age</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * /</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * desc desc desc</span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@typedef</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">*</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> name</span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">:</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">string</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">;</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">*</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> age</span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">:</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">number</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">;</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">*</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> count</span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">:</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> string </span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">|</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> number</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">;</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name operator" style="color:#393A34;font-style:italic">*</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">ObjectTypeName</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></div><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * /</span><br></div></code></pre></div></div>
<p>使用类型</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@type</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">TypeName</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> **/</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> a </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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@type</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">ObjectTypeName</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> **/</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> obj </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></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="jsdoc-中类型和-typescipt中类型的区别">JSDOC 中类型和 Typescipt中类型的区别<a href="https://blog.mengfei.tech/blog/write-ts-in-js#jsdoc-%E4%B8%AD%E7%B1%BB%E5%9E%8B%E5%92%8C-typescipt%E4%B8%AD%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8C%BA%E5%88%AB" class="hash-link" aria-label="Direct link to JSDOC 中类型和 Typescipt中类型的区别" title="Direct link to JSDOC 中类型和 Typescipt中类型的区别" translate="no">​</a></h2>
<ol>
<li class="">不支持泛型。</li>
<li class="">JSDOC 本质就是注释， 无法支持， ts的类型检查。只能提供类型提示。</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="jsdoc-好处">JSDOC 好处<a href="https://blog.mengfei.tech/blog/write-ts-in-js#jsdoc-%E5%A5%BD%E5%A4%84" class="hash-link" aria-label="Direct link to JSDOC 好处" title="Direct link to JSDOC 好处" translate="no">​</a></h2>
<ol>
<li class="">注释更加规范化，</li>
<li class="">让js 具备类型提示，代码提示。</li>
<li class="">增加js代码可读性，可维护性。</li>
<li class="">可以直接生成 api 文档。</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="使用jsdoc-的开源项目">使用JSDOC 的开源项目<a href="https://blog.mengfei.tech/blog/write-ts-in-js#%E4%BD%BF%E7%94%A8jsdoc-%E7%9A%84%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE" class="hash-link" aria-label="Direct link to 使用JSDOC 的开源项目" title="Direct link to 使用JSDOC 的开源项目" translate="no">​</a></h2>
<ul>
<li class="">loadash <a href="https://github.com/lodash/lodash" target="_blank" rel="noopener noreferrer" class="">https://github.com/lodash/lodash</a></li>
<li class="">axios <a href="https://github.com/axios/axios" target="_blank" rel="noopener noreferrer" class="">https://github.com/axios/axios</a></li>
<li class="">mathjs <a href="https://github.com/josdejong/mathjs" target="_blank" rel="noopener noreferrer" class="">https://github.com/josdejong/mathjs</a></li>
<li class="">ramda <a href="https://github.com/ramda/ramda" target="_blank" rel="noopener noreferrer" class="">https://github.com/ramda/ramda</a></li>
</ul>]]></content:encoded>
            <category>typescript</category>
        </item>
        <item>
            <title><![CDATA[AI 笔记]]></title>
            <link>https://blog.mengfei.tech/blog/ai-notes</link>
            <guid>https://blog.mengfei.tech/blog/ai-notes</guid>
            <pubDate>Mon, 19 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[AI 相关笔记占位，后续补充模型使用与工程实践。]]></description>
            <content:encoded><![CDATA[<p>这里收集 AI 相关的笔记与实践，导航「AI」会进入该标签下的文章列表。</p>
<p>后续会补充模型使用、提示词和工程实践。</p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[Powershell 下无法使用 npm 全局包]]></title>
            <link>https://blog.mengfei.tech/blog/powershell-windows</link>
            <guid>https://blog.mengfei.tech/blog/powershell-windows</guid>
            <pubDate>Thu, 20 May 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Powershell 下无法使用 npm 全局包]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="类似yarn 报错" src="https://blog.mengfei.tech/assets/images/2020041517270719-aea1a1e808d3eab52852e9443dbe4439.png" width="899" height="206" class="img_ev3q"></p>
<p>管理员启动 powershell</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">set-ExecutionPolicy RemoteSigned</span><br></div></code></pre></div></div>
<p>关闭 powershell， 重新启动</p>]]></content:encoded>
            <category>windows</category>
            <category>nodejs</category>
        </item>
    </channel>
</rss>